Why do hooks that wrap a resolved handler never observe some requests the server actually received?
answer
- coverage equals invocations, not requests
- everything refused earlier is invisible
- the gap between altitudes is the taxonomy
- sees the decision, not the delivered response
basics
~20 sA handler-aware hook runs only when a handler is invoked, so anything refused earlier — no route match, wrong method, unacceptable media type, a body that failed to convert, an outer credential check — is answered without ever reaching it.
solid answer
~40 sThat altitude wraps an invocation, so its coverage is exactly the set of requests that got one. Everything the framework answers earlier is invisible to it: a target that matched no route, a method the route does not support, a media type it cannot accept or produce, a body that failed to parse or convert into the declared parameters, a credential check that ran further out, a payload rejected for size, a response served by an earlier stage, and a client that disconnected mid-request. The practical symptom is a measurement gap — counts taken there are lower than counts taken at the edge, and the difference is the entire population of rejected traffic. Diagnose it by comparing the two altitudes; the gap itself is the error taxonomy you were missing.
go deeper
Remember the coverage rule: a hook that wraps the handler runs only when a handler runs. Unmatched targets, wrong methods and rejected bodies never get that far.
List the pre-dispatch outcomes concretely — no match, method mismatch, unacceptable media type, conversion failure, an outer refusal — and explain that each is answered without an invocation.
Demonstrate the diagnosis: compare counts across altitudes, subtract, and break the difference down by returned status before concluding anything about the hook itself.
Own the consequence in design review: any claim that must hold for all traffic cannot rest on an altitude whose coverage another stage decides, and a split concern is a coupling someone must maintain.
## The rule that produces the blind spot A handler-aware hook exists to wrap **an invocation of the resolved handler**. That is its whole contract, and its coverage follows mechanically: if no handler is invoked, the hook does not run. Every request the framework can answer without invoking application code is therefore invisible at that altitude — not suppressed, not filtered, simply never presented. This is the mirror image of the edge's weakness. The edge understands the least about a request and sees every one the server accepted; the handler-aware altitude understands a request best and sees the fewest. ## What is answered before an invocation happens - **No route matched the target** — the framework produces a `404` itself. - **The target matched but the method did not** — a `405`, usually with an `Allow` header listing what the route does support. - **Content negotiation failed** — the request's media type is one the route cannot accept (`415`), or it asks for a representation the route cannot produce (`406`). - **The body failed to parse or convert** into the declared parameter types, or failed validation that runs during dispatch — commonly a `400` or `422`, decided before the handler body starts. - **A check further out refused the request** — an identity or authorization decision made at an outer altitude answers `401` or `403` without delegating inward. - **The request was rejected on size or shape** — an oversized payload (`413`), a malformed request line, or header limits enforced at the server edge. - **An earlier stage answered it entirely** — a redirect, a conditional request satisfied by a cached validator, a static asset served without dispatch. - **The client disappeared** — a disconnect or timeout before dispatch completed means there was never anything to wrap. ## The symptom, and how to read it The failure mode is almost never "the hook is broken". It is a **quiet undercount** that only shows up when two altitudes are compared: | Observation | Likely reading | |---|---| | Edge count noticeably exceeds handler-aware count | The gap is traffic refused before dispatch — that is the shape of the problem, not noise | | An audit trail has no record of an incident a client reported | The request was rejected before invocation, so the audit never saw it | | Error rates look flat while clients report failures | Failures are concentrated in statuses produced outside the invocation | | A route shows zero traffic despite client logs | Requests are being refused at matching, on method, or on media type | The diagnostic procedure is short: 1. Count the same traffic at the outermost altitude and at the handler-aware altitude, over the same window. 2. Subtract. The difference is the population that never reached a handler. 3. Break that difference down by the status actually returned — the statuses above are the taxonomy. 4. Only then decide whether the concern is still at the right altitude. ## The design consequence Any concern whose value depends on seeing **all** traffic — a complete record of what the service was asked to do, a total request count, a safety property that must hold for every request — cannot live only at the handler-aware altitude, because that altitude's coverage is defined by a decision made further out. Conversely, any concern that needs the identity of the operation, its converted arguments, or its result has nowhere else to go. When one concern needs both, it gets split: capture the broad fact outward, decide with the precise fact inward, and accept that the two halves are now coupled. There is a second, subtler consequence. A handler-aware hook also sees a **partial view outbound**. It observes the value returned or the exception thrown, but what the client received is decided after it returns, when the value is serialized and outer stages may translate, rewrite or fail. So even for the requests it does see, it knows what the application *decided*, not what the client *got*. ## Frameworks differ here Frameworks differ on how much of dispatch happens before an invocation: some resolve and convert every argument before any handler-aware hook runs, so conversion failures are invisible at that altitude; others expose an attachment point that runs even when resolution fails, so it can observe the failure. The safe assumption when designing is the narrow one — treat handler-aware coverage as "requests that actually reached the handler" and put any all-traffic claim somewhere that genuinely sees all traffic.
- A team asks why their audit trail has no entry for a rejected request; how do you explain it in one line?The audit hook wraps the handler, and no handler ran. A target that matched nothing, a method or media type the route refuses, a body that failed conversion, or a credential check further out all produce a response without an invocation, so the audit never had an event to record. If the audit must cover attempts, it belongs at an altitude that sees attempts.
- Why can a handler-aware hook report success for a request the client saw fail?Because it reports the handler's decision, not the delivered response. Serialization can fail, content negotiation can reject the chosen representation, and an outer stage can rewrite or replace the response after the hook has already finished unwinding. Only an altitude that observes the finished status and bytes can claim what the client received.
- What is the cheapest way to confirm that a measurement gap is rejected traffic rather than a broken hook?Compare counts at the outermost altitude with counts at the handler-aware altitude over the same window, then break the difference down by returned status. If the excess resolves into recognizable pre-dispatch statuses, the hooks are working exactly as defined; a gap that does not resolve that way points at a registration or scoping problem instead.
saying these in an interview costs you the question
- Assumes a handler-aware hook runs for every request the server received
- Treats counts from that altitude as the service's total traffic
- Believes the framework invokes the hook with no handler for unmatched requests
- Says a missing audit record proves the request never arrived
- Reports the handler's outcome as the status the client received
- Thinks conversion failures are always visible to handler-aware hooks