Problem
The protocol says listener implementations must not raise into the core, but listener hooks are invoked directly in the engine and pipeline. A bug in logging, metrics export, or a custom listener can therefore:
- replace a successful protected result with an observability exception;
- mask the dependency's original exception;
- interrupt state-transition bookkeeping;
- prevent fallback/retry behavior from completing.
A resilience primitive should not let optional observability become a new failure source.
Proposed policy
Route every EventListener callback through one shared safe dispatcher:
- catch ordinary
Exception from the listener;
- log it through the stdlib
interlock logger with hook and breaker/strategy context;
- continue the breaker/pipeline operation;
- never catch
BaseException kinds such as KeyboardInterrupt or cancellation.
User-supplied policy callbacks that are not listener hooks (for example a tenacity before_sleep hook or a fallback function) should retain their current behavior.
Acceptance criteria
- Apply the same policy to core, storage, and pipeline listener hooks.
- Preserve backward compatibility with listeners that omit newer optional hooks.
- Add tests for successful calls, failed calls, rejections, transitions, storage degradation/recovery, retry, bulkhead rejection, and fallback when the listener raises.
- Ensure the listener failure is observable in logs and never silently swallowed.
- Document the failure policy in the observability guide and
EventListener protocol.
Problem
The protocol says listener implementations must not raise into the core, but listener hooks are invoked directly in the engine and pipeline. A bug in logging, metrics export, or a custom listener can therefore:
A resilience primitive should not let optional observability become a new failure source.
Proposed policy
Route every
EventListenercallback through one shared safe dispatcher:Exceptionfrom the listener;interlocklogger with hook and breaker/strategy context;BaseExceptionkinds such asKeyboardInterruptor cancellation.User-supplied policy callbacks that are not listener hooks (for example a tenacity
before_sleephook or a fallback function) should retain their current behavior.Acceptance criteria
EventListenerprotocol.