From eea3a78140e003cbd18be007f6fba0ba70623cf7 Mon Sep 17 00:00:00 2001 From: Bendik Aagaard Lynghaug Date: Sat, 3 Oct 2026 09:15:56 +0000 Subject: [PATCH] main: clear error messages and exit codes instead of panics Missing/invalid config, unwritable config target, failed Wayland connect and bad arguments now print one line to stderr and exit 1 rather than panicking with "uh" or a serde backtrace. Co-Authored-By: Claude Fable 5.1 --- src/draw.rs | 2 +- src/main.rs | 49 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index fdc6812..a6b8d2f 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -82,7 +82,7 @@ pub struct Font<'a> { } impl<'a> Font<'a> { - pub fn new(font: FontRef<'a>, size: f32) -> Font { + pub fn new(font: FontRef<'a>, size: f32) -> Font<'a> { Font { glyphs: HashMap::new(), font, diff --git a/src/main.rs b/src/main.rs index 6084208..a2ba0b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,10 +56,14 @@ OPTIONS: ); } +fn die(msg: String) -> ! { + eprintln!("wldash: {}", msg); + std::process::exit(1); +} + fn ensure_dir_exists(path: &str) { - match fs::create_dir_all(path) { - Ok(_) => (), - Err(err) => panic!("error creating directory: {}", err), + if let Err(err) = fs::create_dir_all(path) { + die(format!("error creating directory {}: {}", path, err)); } } @@ -95,7 +99,7 @@ fn main() { match args.next() { Some(ref s) if s == "--config" => match args.next() { Some(ref s) => config_file = s.clone(), - None => panic!("missing argument to --config"), + None => die("missing argument to --config".to_string()), }, Some(ref s) if s == "--write-default-config" => { let config = match args.next() { @@ -103,17 +107,23 @@ fn main() { Some(ref s) if s == "v2" => Config::generate_v2(false), Some(ref s) if s == "toplevel" => Config::generate_v2(true), None => Config::generate_v2(false), - Some(s) => panic!("unknown argument: {}", s), + Some(s) => die(format!("unknown argument to --write-default-config: {}", s)), }; - match File::create(config_file) { - Ok(f) => serde_yaml::to_writer(f, &config).unwrap(), - Err(_) => panic!("uh"), + match File::create(&config_file) { + Ok(f) => { + if let Err(e) = serde_yaml::to_writer(f, &config) { + die(format!("could not serialize config: {}", e)); + } + } + Err(e) => die(format!("could not write {}: {}", config_file, e)), } std::process::exit(0); } Some(ref s) if s == "--desktop-refresh" => { let v = load_desktop_files(); - write_desktop_cache(&v).unwrap(); + if let Err(e) = write_desktop_cache(&v) { + die(format!("could not write desktop cache: {}", e)); + } std::process::exit(0); } Some(ref s) if s == "--help" => { @@ -128,7 +138,10 @@ fn main() { } } - let conn = Connection::connect_to_env().unwrap(); + let conn = match Connection::connect_to_env() { + Ok(c) => c, + Err(e) => die(format!("could not connect to the Wayland display: {}", e)), + }; let event_queue = conn.new_event_queue(); let qhandle: QueueHandle = event_queue.handle(); @@ -204,9 +217,15 @@ fn main() { let mut fm = FontMap::new(); - let config: Config = match File::open(config_file) { - Ok(f) => serde_yaml::from_reader(f).unwrap(), - Err(_) => panic!("configuration file missing: try 'wldash --write-default-config'"), + let config: Config = match File::open(&config_file) { + Ok(f) => match serde_yaml::from_reader(f) { + Ok(c) => c, + Err(e) => die(format!("invalid configuration {}: {}", config_file, e)), + }, + Err(e) => die(format!( + "could not open configuration {}: {} (try 'wldash --write-default-config')", + config_file, e + )), }; if let Some(true) = config.server { @@ -292,7 +311,7 @@ fn main() { } let mut force = false; - if state.bufmgr.buffers.len() == 0 { + if state.bufmgr.buffers.is_empty() { state.add_buffer(&qhandle); force = true; } @@ -316,7 +335,7 @@ fn main() { } }; - if buf.last_damage.len() == 0 { + if buf.last_damage.is_empty() { for _ in 0..state.widgets.len() { buf.last_damage.push(Geometry::new()); }