From 778c953f2e5d8cf84e4eb95ecb782a015f532f8c Mon Sep 17 00:00:00 2001 From: x01dc Date: Tue, 14 Jul 2026 12:59:54 +0200 Subject: [PATCH] fix(flomni): raise instead of silently returning when a fermat scan is declined tomo_scan_projection() always runs a Fermat scan; when single_point_instead_of_fermat_scan is on and _internal isn't passed, it asks "Run a fermat scan anyway?" and, on "no", used to just print "Aborted." and return -- no exception. Real incident: a custom at_each_angle hook called this without _internal=True, got asked at every projection angle, declining silently skipped each one, and the eventual Ctrl-C (KeyboardInterrupt, which tomo_queue_execute()'s `except Exception` does not catch) left the job stuck at status "running" forever with no live process behind it. Declining now raises FlomniError, which (with the earlier scan_repeat exc_handler fix) isn't retried and correctly fails the job, marking it "incomplete" and pausing the queue -- the crash-resume contract tomo_queue_execute() already documents, instead of silent data loss followed by an untraceable stuck state. Sim-verified: direct decline raises with a clear message; through the queue via a hook missing _internal=True, the job ends up "incomplete", not stuck "running" or silently "done". Co-Authored-By: Claude Sonnet 5 --- .../plugins/flomni/flomni.py | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 101d00b..a8ddc0a 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -3353,8 +3353,28 @@ class Flomni( " acquisition at this angle use tomo_acquire_at_angle(angle) instead.\x1b[0m" ) if not self.OMNYTools.yesno("Run a fermat scan anyway?", "n"): - print("Aborted. Use tomo_acquire_at_angle(angle) for a single-point acquisition.") - return + # Raise, don't silently return: this runs inside + # tomo_scan()'s per-angle loop (directly, or via a custom + # at_each_angle hook) as often as not, and a bare `return` + # here means the projection that was supposed to happen + # simply never did -- no exception, no incomplete status, + # no trace that data is now missing from the tomogram. A + # real incident: a hook that called this without + # _internal=True got asked at every angle, declining just + # skipped each one silently, and the eventual Ctrl-C (which + # tomo_queue_execute()'s `except Exception` does NOT catch, + # since KeyboardInterrupt isn't an Exception) left the job + # stuck at status "running" forever with no process behind + # it. Raising here means a decline now correctly fails the + # job, marks it "incomplete", and pauses the queue -- + # exactly the crash-resume contract tomo_queue_execute() + # already documents. + raise FlomniError( + "tomo_scan_projection: declined to run a Fermat scan while " + "single_point_instead_of_fermat_scan is on. Use " + "tomo_acquire_at_angle(angle) for a single-point acquisition, " + "or pass _internal=True to force the Fermat scan without asking." + ) dev.rtx.controller.laser_tracker_check_signalstrength()