Negotiate error handler content type on every request - #3464
Conversation
The ErrorHandler cached the content type negotiated from the first request's Accept header and reused it for the lifetime of the handler instance. Applications sharing one handler across requests (long-running worker runtimes such as Swoole, RoadRunner or Laravel Octane) kept serving error responses in the first request's format regardless of later clients' Accept headers. Recompute the content type from each request unless forceContentType() was called, which keeps its existing override semantics.
|
Thanks for the PR. I think the bigger question here is whether Slim should support reusing the same application object graph across multiple requests at all. Slim traditionally follows PHP shared-nothing request lifecycle. Long-running workers like RoadRunner, Swoole or Octane change that model and can keep the same objects alive between requests. If we want to officially support that lifecycle, changing only If we want to support persistent workers, I think we need to look at this more broadly and decide what kind of request reuse Slim should support. If this is not a lifecycle Slim intends to support, then I don't think we should start fixing individual cases for it here. Also this patch changes the behavior of @akrabat What do you think? |
|
The The other fields on
This PR doesn't try to make Slim a worker framework. It splits "forced" from "already negotiated" so the documented force API still works when the handler instance outlives one request. |
The ErrorHandler caches the content type negotiated from the first request's Accept header (
$this->contentTypeis set only when currently null) and reuses it for the lifetime of the handler instance. Applications that share oneErrorHandleracross requests, such as long-running worker runtimes (Swoole, RoadRunner, Laravel Octane) where the container-built handler persists, keep serving error responses in the first request's negotiated format regardless of later clients' Accept headers. A single JSON client pins every subsequent browser or XML client to JSON error pages until process restart.This change recomputes the content type from each incoming request. The existing override semantics are preserved: once
forceContentType()is called, the forced value wins for all subsequent requests.