Source code for melder.utilities.custom_exceptions.phase_timeout_error

from melder.utilities.custom_exceptions.phase_scheduler_error import PhaseSchedulerError



[docs] class PhaseTimeoutError(PhaseSchedulerError): """ Purpose: Signal that one scheduled phase exceeded its configured barrier timeout and the resolution pipeline was aborted. Raised When: A phase's units of work do not all report before the barrier deadline. The scheduler runs phases behind barriers, so a phase that never completes would otherwise stall conjure indefinitely; the timeout turns that hang into a diagnosable failure. What To Do About It: A timeout usually means work is blocked, not slow. Look for a constructor that blocks on I/O, a lock held across a phase boundary, or a hook waiting on something that never arrives. Raising the timeout budget hides the hang rather than fixing it. Contract: - Identifies the phase that timed out. - Preserves the configured timeout value in milliseconds for callers, logs, and higher-level scheduler diagnostics. - Subclasses `PhaseSchedulerError`, so callers may catch either the specific timeout or the whole scheduler family. Owned State: - `phase_name`: the phase that exceeded its budget. - `timeout_ms`: the configured budget, in milliseconds. Registration: Exported on the public root surface; import, raise, and catch freely. Subsystem Context: One of the 11 `utilities/custom_exceptions/` types and one of two concrete children of `PhaseSchedulerError`. Its sibling `PhaseExecutionError` means the work RAN and failed; this one means the work never reported at all. That distinction is the whole reason both types exist. System Context: Fires during conjure, at a phase barrier. Because it aborts before a Conduit exists, nothing has been registered into Aether and no cleanup cascade is owed - the failure is total and leaves no partial world. AGENT_ACCESS: public AGENT_PURPOSE: access: public. Raised when a conjure phase exceeds its barrier timeout; phase_name + timeout_ms locate it. Usually a blocked constructor/lock/hook, not slow work. """ def __init__(self, phase_name: str, timeout_ms: int) -> None: """ Build a timeout error for one named phase. Args: phase_name (str): Name of the scheduler phase that exceeded its timeout budget. timeout_ms (int): Configured timeout in milliseconds. Contract: - COMPOSES ITS OWN MESSAGE from the phase name and timeout, so callers pass structured values rather than pre-formatted text. - RETAINS `phase_name` and `timeout_ms` as attributes, so handlers can branch on which phase timed out without parsing the message. - Signals that the resolution pipeline was ABORTED, not merely delayed - this is a terminal condition for that run. Threading: Plain construction; no shared state. Lifecycle / Cleanup: None - it is an exception value. Returns: None. """ msg = ( f"Phase '{phase_name}' exceeded barrier timeout " f"({timeout_ms} ms). Resolution pipeline aborted." ) super().__init__(msg) self.phase_name = phase_name self.timeout_ms = timeout_ms