You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TASK-049: fire handler_exception + wire internal_error_handler alias
Convert the DR-009 §5.2 dispatch-exception path into a hookable chain.
User-added handler_exception hooks run first in registration order; the
v1 internal_error_handler becomes a last-position alias slot. The first
hook to return respond_with() wins; a throwing hook is caught and the
chain continues (DR-012 §4.10 - the one phase where exception-in-hook
does NOT abort, because the chain itself IS exception recovery). When
every hook and the alias either throw or pass(), the dispatcher emits
the hardcoded empty-body 500 directly without re-invoking the alias.
Implementation:
- webserver_impl gains handler_exception_alias_, a dedicated single-slot
std::function written once at construction (never in the user vector,
so its last-position ordering is structural).
- fire_handler_exception in hook_handle.cpp snapshots the user vector
under shared_lock, iterates with per-hook try/catch, then invokes the
alias slot.
- dispatch_resource_handler's two catch arms now route through
handle_dispatch_exception() which takes the chain path when any user
hook is registered OR the alias is wired, and falls back to the v1
run_internal_error_handler_safely path otherwise.
- install_default_alias_hooks_ writes the alias slot via the extracted
install_internal_error_alias_ helper (keeps host CCN at baseline).
- Doxygen on create_webserver::internal_error_handler and the class-
level error-propagation contract on webserver document the alias and
reference DR-012.
Tests (all 68 pass sequentially):
- hooks_handler_exception_chain: A=pass, B=respond_with(418), alias C
never invoked.
- hooks_handler_exception_user_handler_throws_continues_chain: A
throws; chain continues to B; "alpha" surfaced in log_error.
- hooks_handler_exception_fallback_to_hardcoded_500: A=pass, B throws,
alias C throws -> empty-body 500; alias C called exactly once (pins
no-re-entry contract).
- hooks_handler_exception_slot: unit pin that internal_error_handler
populates the dedicated last-position slot and leaves the user
vector at size 0.
- hooks_no_firing: handler_exception added to the not_yet_wired exclude
list with explanatory comment.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments