Construct the error Log per request instead of sharing a singleton#6
Conversation
The `log` resource was registered on the root di Container, which caches the factory result. With enable_coroutine on, that single Log instance was shared across concurrent requests, so error context (namespace, message, tags) from one request could bleed into another. The error action is the only consumer of `log`, so build a fresh Log inside it (matching how Appwrite's worker/cli error handlers construct their own Log) and drop the shared resource registration.
Greptile SummaryThis PR fixes a request-context bleed bug where a singleton
Confidence Score: 5/5The change is safe to merge; it narrows scope from a shared singleton to a local allocation with no other behavioral changes. Both files have minimal, targeted changes. The root cause (singleton No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "Construct the error Log per request inst..." | Re-trigger Greptile |
What
Follow-up to #5 addressing a Greptile review comment.
The
logresource was registered on the rootutopia-php/diContainer.Container::get()caches the factory result, so the per-request context (a child container) falls through to the root and every request receives the sameLoginstance. Withenable_coroutineenabled, concurrent requests share that instance, so error context set in the error handler (setNamespace,setMessage,addTag, ...) can bleed between requests.geodbandloggerare correctly long-lived singletons (read-only DB reader / log provider). Onlylogis request-scoped.Fix
The error action is the only consumer of
log, so it now builds a freshLoglocally — the same pattern Appwrite's worker/cli/realtime error handlers use — and the sharedlogresource registration is removed.Testing
composer lint(pint) andcomposer check(phpstan level 8) pass.GET /v1/health→{"status":"ok"}GET /v1/ips/8.8.8.8without key →401(Init throws → error action)GET /v1/nope→404(no route → error action)GET /v1/ips/1.1.1.1with key → correct payload