From 5991920c156b5d7515e9c90cbe45dc0716dfb57c Mon Sep 17 00:00:00 2001 From: x01dc Date: Mon, 13 Jul 2026 16:54:15 +0200 Subject: [PATCH] fix(flomni): stop retrying _tomo_scan_at_angle on a definite FlomniError Found by testing the new at_each_angle_hook feature against the live sim: _tomo_scan_at_angle is wrapped in @scan_repeat(max_repeats=10, default=True), which retries *any* exception, including a FlomniError raised for an unregistered hook -- a condition that will never succeed by retrying. The operator saw 10 silent retries before a generic "TooManyScanRestarts", with the actual, actionable error message buried in __cause__ instead of reaching tomo_queue_execute()'s printed failure message. Adds an exc_handler that skips the retry for any FlomniError (a definite, non-transient failure by convention throughout this file), letting the real message surface immediately. General fix, not narrowly scoped to hooks -- every other FlomniError this method could raise gets the same benefit. Co-Authored-By: Claude Sonnet 5 --- .../bec_ipython_client/plugins/flomni/flomni.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 9e3c7c9..5f7895a 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -2422,7 +2422,20 @@ class Flomni( # finally do the scan at this angle self._tomo_scan_at_angle(angle, subtomo_number) - @scan_repeat(max_repeats=10, default=True) + @staticmethod + def _retry_unless_flomni_error(exc: Exception, attempt: int) -> bool: + """scan_repeat() exc_handler: retry any exception except FlomniError. + + FlomniError marks a definite, non-transient failure (bad config, + unmet precondition, ...) -- e.g. _at_each_angle() raises it when a + job's at_each_angle_hook name isn't registered in this session. + Retrying that up to max_repeats times just burns 10 attempts before + surfacing a much less informative TooManyScanRestarts, instead of + the actual, actionable error message immediately. + """ + return not isinstance(exc, FlomniError) + + @scan_repeat(max_repeats=10, default=True, exc_handler=_retry_unless_flomni_error) def _tomo_scan_at_angle(self, angle, subtomo_number): if 0 <= angle < self.tomo_angle_range + 0.05: