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 <noreply@anthropic.com>
This commit is contained in:
x01dc
2026-07-13 16:54:15 +02:00
co-authored by Claude Sonnet 5
parent 48647bf0d9
commit 5991920c15
@@ -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: