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 <noreply@anthropic.com>
This commit is contained in:
Bendik Aagaard Lynghaug
2026-10-03 09:15:56 +00:00
co-authored by Claude Fable 5.1
parent 8c319cffc6
commit eea3a78140
2 changed files with 35 additions and 16 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ pub struct Font<'a> {
} }
impl<'a> 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 { Font {
glyphs: HashMap::new(), glyphs: HashMap::new(),
font, font,
+34 -15
View File
@@ -56,10 +56,14 @@ OPTIONS:
); );
} }
fn die(msg: String) -> ! {
eprintln!("wldash: {}", msg);
std::process::exit(1);
}
fn ensure_dir_exists(path: &str) { fn ensure_dir_exists(path: &str) {
match fs::create_dir_all(path) { if let Err(err) = fs::create_dir_all(path) {
Ok(_) => (), die(format!("error creating directory {}: {}", path, err));
Err(err) => panic!("error creating directory: {}", err),
} }
} }
@@ -95,7 +99,7 @@ fn main() {
match args.next() { match args.next() {
Some(ref s) if s == "--config" => match args.next() { Some(ref s) if s == "--config" => match args.next() {
Some(ref s) => config_file = s.clone(), 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" => { Some(ref s) if s == "--write-default-config" => {
let config = match args.next() { 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 == "v2" => Config::generate_v2(false),
Some(ref s) if s == "toplevel" => Config::generate_v2(true), Some(ref s) if s == "toplevel" => Config::generate_v2(true),
None => Config::generate_v2(false), 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) { match File::create(&config_file) {
Ok(f) => serde_yaml::to_writer(f, &config).unwrap(), Ok(f) => {
Err(_) => panic!("uh"), 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); std::process::exit(0);
} }
Some(ref s) if s == "--desktop-refresh" => { Some(ref s) if s == "--desktop-refresh" => {
let v = load_desktop_files(); 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); std::process::exit(0);
} }
Some(ref s) if s == "--help" => { 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 event_queue = conn.new_event_queue();
let qhandle: QueueHandle<State> = event_queue.handle(); let qhandle: QueueHandle<State> = event_queue.handle();
@@ -204,9 +217,15 @@ fn main() {
let mut fm = FontMap::new(); let mut fm = FontMap::new();
let config: Config = match File::open(config_file) { let config: Config = match File::open(&config_file) {
Ok(f) => serde_yaml::from_reader(f).unwrap(), Ok(f) => match serde_yaml::from_reader(f) {
Err(_) => panic!("configuration file missing: try 'wldash --write-default-config'"), 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 { if let Some(true) = config.server {
@@ -292,7 +311,7 @@ fn main() {
} }
let mut force = false; let mut force = false;
if state.bufmgr.buffers.len() == 0 { if state.bufmgr.buffers.is_empty() {
state.add_buffer(&qhandle); state.add_buffer(&qhandle);
force = true; 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() { for _ in 0..state.widgets.len() {
buf.last_damage.push(Geometry::new()); buf.last_damage.push(Geometry::new());
} }