From ffc2c553e87ee494c2e7905468e2c1c65534bd00 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Tue, 3 Nov 2026 15:07:02 +0100 Subject: [PATCH] Drop missing files from the recent list when opening them fails (#2706) * Drop missing files from the recent list when opening them fails Fixes #2700 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 * Keep a recent file whose existence can't be checked (CodeRabbit) Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Haiku 5.5 Co-authored-by: Brandon Thomas --- crates/ui-egui/src/lib.rs | 8 +++++++- crates/ui-egui/tests/recent_files.rs | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 3e635ea2f..d27712da2 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -570,7 +570,13 @@ impl CadApp { /// Add the files whose background read has finished; report the ones that failed as a failed /// OPEN is reported. Called every frame. pub fn finish_opening(&mut self) { - for (_, outcome) in self.opening.poll() { + for (path, outcome) in self.opening.poll() { + // A recent file that is gone can never be opened again: drop it from the list. A path + // whose existence can't be checked (a folder that denies access) stays. + if outcome.is_err() && matches!(path.try_exists(), Ok(false)) { + let path = path.to_string_lossy(); + self.ui.recent_files.retain(|p| *p != path); + } let r = match outcome { Ok(f) => self.session.finish_open(f).map_err(|e| e.to_string()), Err(e) => Err(e), diff --git a/crates/ui-egui/tests/recent_files.rs b/crates/ui-egui/tests/recent_files.rs index 34d460255..34aa6e2e8 100644 --- a/crates/ui-egui/tests/recent_files.rs +++ b/crates/ui-egui/tests/recent_files.rs @@ -135,3 +135,15 @@ fn start_page_lists_recent_files_and_opens_one_on_click() { assert_eq!(app.session.state().ok().and_then(|s| s.path.clone()), Some(plan.clone())); assert_eq!(app.ui.recent_files, [plan, section]); } + +#[test] +fn a_recent_file_that_no_longer_exists_is_dropped_when_opening_it_fails() { + let (_dir, plan, _section) = drawings("missing"); + let mut app = CadApp::new(Session::empty(), Services::default()); + let gone = "/nonexistent/dir/gone.dxf".to_string(); + app.ui.recent_files = vec![gone.clone(), plan.clone()]; + let id = open_recent(&app).into_iter().find(|(l, _)| l == "gone.dxf").map(|(_, id)| id).unwrap_or_default(); + menus::activate(&mut app, &id); + settle(&mut app); + assert_eq!(app.ui.recent_files, [plan], "the stale entry is removed, the others stay"); +}