Core: Unable to access request actor in error handler

Created on 13 Aug 2019  路  3Comments  路  Source: flarum/core

Introduced in #1843 which introduces an alternative instead of middleware for error handling.

The "problem" here is that PSR-7 requests and responses are immutable. The ErrorHandler middleware basically passes on the request it received from the outside world to inner middleware. One of these middlewares extracts cookies, headers etc. from the response to determine the actor, which is then stored as a "request attribute" on the request. Once you add a new request attribute, you're creating a new request instance, though - which means the request instance known by the ErrorHandler is unchanged. This was a design decision when PSR-7 was created.

TL;DR: Request object passed to error handler is not the same instance as the one passed to middleware. Actor is unavailable.

needs-discussion typbug

All 3 comments

My plan is the following:

  • Add a simple, single middleware before the error handler middleware that injects a ActorReference (optionally with a better name) into the request as an attribute. Because that reference is an object, it will be the same across middleware even when they receive a different request instance.
  • As the name suggests (does it?), the ActorReference is mutable. Later middleware (e.g. AuthenticateWithSession) can call setActor() on the reference once they do authentication.
  • From that point on, all middleware - most importantly the error handler - can access the actor from the reference, even if it was added later in the stack. (Note: For early middleware like the error handler, the actor will only be available after getting a response from other middleware, not when passing a request in to the stack.)

@datitisev Does this make sense? It should solve your problem, right?

At first I thought: "Woah, this is just a huge hack". But it could turn out to be quite useful, as this could even be used to inject an actor into Flarum e.g. when building integrations with an existing website's authentication system.

@franzliedke As far as I can tell, yes, it makes sense and should work. Thanks for writing out the plan 馃檪.

This works well with https://github.com/flarum/core/issues/869#issuecomment-612838885. We can keep both systems (actor as direct attribute, and ActorReference) at the start, then deprecate actor as direct attribute, while encouraging people to use RequestUtil::actorFromRequest($request) as pseudo-encapsulation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tobyzerner picture tobyzerner  路  4Comments

luceos picture luceos  路  4Comments

gingerbeardman picture gingerbeardman  路  4Comments

datitisev picture datitisev  路  4Comments

webpigeon picture webpigeon  路  3Comments