Repository navigation
ResponseReceived tells a slow upstream API apart from a slow mapper. ResponseMapped::durationMs covers the whole operation, so it shows which action is slow but not where the time goes; the new event is emitted once the client has returned a response and before mapping.
#[AsEventListener]
public function received(ResponseReceived $event): void
{
// $event->durationMs — everything before mapping (resolution, auth, middleware, transport)
}
// mapping time = ResponseMapped::timestamp − ResponseReceived::timestampResponseReceived followed by RequestFailed means the API answered and mapping failed. Transport failures and the 401 that triggers a token refresh don't emit it. See ADR 0021 and the timing semantics.
Added
ResponseReceivedlifecycle event, emitted once the client has returned a response and before mapping: insend()(static and dynamic auth alike) and for eachsendMany()item.ResponseMapped::timestamp − ResponseReceived::timestampis the mapping time, andResponseReceivedfollowed byRequestFailedmeans the API answered and mapping failed. Restores the pre-mapping split that v7'sHttpResponseReceivedprovided and the v8 event rework dropped. Code asserting an exact event sequence now sees it betweenRequestSentandResponseMapped.
Fixed
debug:integration <name>no longer fails with "Unable to inspect actions" on integration YAML that declares the v9.3.0defaults:section; it skipsdefaults:likewebhooks:instead of treating it as an action.
Documentation
- Added
docs/upgrade-9.0.md, the migration guide for the v9.0.0 context-only path resolution change. - Fixed examples that did not work against the code: the response-header lookup in
mappers-and-responses.md(Symfony HttpClient header names are lowercase), theExponentialBackoffnamed argument inadvanced/resilience.md(maxAttempts, notmaxRetries) and the GraphQL body inadvanced/architecture/clients.md(missingcreate()). webhook.mdnow matches Symfony'sWebhookController: an accepted event is dispatched to Messenger before the 202 is sent, so with the default synchronous bus the consumer runs inside the webhook request.- The developer guide's profiler sections now describe the
bodyClassfield and theprofiler_payloadsopt-in instead of saying body and context contents are never stored. - Refreshed the latest-release marker in the docs and landing page, and the measured results in
docs/advanced/quality.md. - Smaller alignments in
CLAUDE.md,CONTRIBUTING.md,ai-agent-usage.mdand several docblocks.
Full changelog: v9.3.1...v9.4.0