fix(app): don't crash when a save's filesystem prep fails - #2393
Conversation
00e4615 to
e29c2d6
Compare
Verdict: Reviewed the diff (medium-effort Checks:
|
Withdrew Nothing is wrong with the change itself, and no re-review is implied. This needs a rebase onto current Merging the approved backlog sooner would stop these from going stale: several PRs are queued behind the same moving |
e29c2d6 to
d300ac9
Compare
Rebased onto current Ran a report-only two-axis review over the rebased diff. No meaningful findings, so I skipped the full review-fix loop:
Local verification on the rebased tree: One cosmetic note on this PR's own description, not the code: it cites Awaiting CI on the rebased head; I will verdict once the checks report. |
Verdict: CI on the rebased head ( Restoring the verdict withdrawn on 2026-07-25: the withdrawal was purely about the Nothing further from me. History is a single logical conventional commit; no reshaping needed. |
d300ac9 to
cb73b71
Compare
save_labels wraps Path.mkdir and os.path.relpath in the same try as write_label_file but caught only LabelFileError. A read-only or full --output directory (OSError) or, on Windows, an image and output on different drives (ValueError) escaped uncaught and crashed the app via the global excepthook, including during auto-save. Catch these like the existing write failures: show the save-error dialog and return False.
cb73b71 to
a902e9e
Compare
save_labelswrapsPath.mkdir(creating the output directory) andos.path.relpath(computing the image's stored relative path) in the sametryaswrite_label_file, but caught onlyLabelFileError.write_label_filere-wraps its own I/O errors intoLabelFileError, so writes were covered, butmkdirandrelpathare not: a read-only or full--outputdirectory raisesPermissionError/OSError, and on Windows an image and output on different drives raisesValueError. Both escaped uncaught and took the whole app down through the global exception hook, including during auto-save (which runs on every edit).They are now caught alongside the existing write failures, matching the raw-
OSError/ValueErrorhandling already used elsewhere at the UI boundary (_open_image_into_state,_on_setting_changed): the save-error dialog is shown andsave_labelsreturnsFalseinstead of crashing.Test plan
tests/e2e/save_error_handling_test.py: parametrized over both documented failure modes (Path.mkdir->PermissionError,os.path.relpath->ValueError); each assertssave_labelsreturnsFalseand shows the error dialog. Both cases fail onmainand pass with the fix.MainWindow(app's real excepthook installed) into a genuinely read-only output dir and triggered auto-save: with the fix the app survives with the dialog and exits cleanly; onmainthe same input hits the excepthook with aPermissionErrortraceback and crashes.uv run ruff check,ruff format --check,ty check, full unit/e2e suite (883 passed) green