Source code for melder.utilities.custom_exceptions.hook_execution_error

[docs] class HookExecutionError(Exception): """ Purpose: Signal that a user-supplied lifecycle hook raised during binding or melding, while preserving enough context to identify WHICH hook failed and WHY. Raised When: A registration callback configured on Spellbook raises during `pre_bind`, `bind_activation` or `post_bind`, or an existing creation/resolution hook raises during Meld. A raising hook stops the current callback chain. A post-bind failure does not imply that registration was rolled back. What To Do About It: The failure is in your hook body, not in Melder. Read `original_exception` for the real cause; `phase` and `hook_name` tell you which registration to look at. Melder does not swallow hook failures, because a hook that silently fails leaves the object half configured, which is worse than a refused resolution. Contract: - Preserves the hook phase and hook identity that failed. - Carries the original exception separately so callers can inspect or re-log the underlying failure without parsing the rendered message. - The rendered message embeds phase, hook name, and the original exception's type and text, so a bare log line is still diagnostic. Owned State: - `phase`: the hook phase that was executing. - `hook_name`: name or representation of the failing hook. - `original_exception`: the exception the hook body raised. Registration: Exported on the public root surface; import, raise, and catch freely. Subsystem Context: One of the 11 `utilities/custom_exceptions/` types. It is the hook-path counterpart to `MeldExecutionError`: that one means Melder's own resolution failed, this one means YOUR code failed during Melder's resolution. Keeping them distinct is what lets a caller tell "the container is broken" apart from "my callback is broken". System Context: Fires inside the bind or meld pipeline while user callbacks execute. Hooks are one of the DGR's documented extension points, so this error is the boundary where user-supplied behavior re-enters Melder's control flow. AGENT_ACCESS: public AGENT_PURPOSE: access: public. Raised when a user lifecycle hook raises during bind or meld; read original_exception, phase, hook_name. It means YOUR callback failed, not Melder. """ def __init__(self, phase: str, hook_name: str, original_exception: Exception) -> None: """ Build a hook-execution failure with preserved source metadata. Args: phase (str): Hook phase such as `pre_cast`, `activation`, or `post_cast`, `pre_bind`, `bind_activation`, or `post_bind`. hook_name (str): Name or representation of the hook that failed. original_exception (Exception): Original exception raised by the hook body. Contract: - PRESERVES THE ORIGINAL EXCEPTION on the instance rather than discarding it, so callers can inspect the underlying failure instead of parsing the message. - Records the PHASE and HOOK NAME separately, so handlers can decide whether a pre-hook or post-hook failure is recoverable. - The composed message names the hook and the original exception type, which is what makes these readable in a log without unwrapping. Threading: Plain construction; no shared state. Lifecycle / Cleanup: None - it is an exception value. Returns: None. """ self.phase = phase self.hook_name = hook_name self.original_exception = original_exception super().__init__(f"[HOOK][{phase}] Hook '{hook_name}' failed: {type(original_exception).__name__}: {original_exception}")