Updated: Comment #N
Proposed commit message:
Issue #2185831 by tim.plunkett, dawehner: Split up ParamConverterManager and stop throwing NotFoundHttpException.
Problem/Motivation
The ParamConverterManager is used for both routing and access checks. However, when it fails to convert a parameter, it throws a NotFoundHttpException, which Drupal catches and returns a 404. This is not appropriate when used outside of the context of routing.
Additionally, the ParamConverterManager is supposed to just manage the parameter converter tagged services. However, it also uses these when acting as a RouteEnhancer.
This means that the AccessManager is asking the ParamConverterManager to enhance the routes, and it should be asking a dedicated RouteEnhancer.
Finally, this contributes to \Drupal::service('router')->match('/admin'); *always* throwing an exception. That's a known route with no params, provided by system module. We can currently *only* match by Request.
Proposed resolution
This splits up the class into two, by adding a ParamConversionEnhancer.
Remaining tasks
Figure out how to turn ParamNotConvertedException into NotFoundHttpException when appropriate.
User interface changes
N/A
API changes
Anyone calling ParamConverterManager::enhance should now call ParamConversionEnhancer::enhance. That is the route_enhancer.param_conversion service.
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | interdiff.txt | 7.05 KB | tim.plunkett |
| #16 | paramconverter-2185831-16.patch | 49.88 KB | tim.plunkett |
Comments
Comment #1
msonnabaum commentedLooks like a very nice improvement.
Comment #4
tim.plunkettSo all of these places are using NotFoundHttpException, but they're not always in an HTTP context.
However, at least some tests will fail, because if you go to /node/1/delete, delete it, and then to /node/1, you should get a 404, not ParamNotConvertedException.
So we need to figure out either a way to know which exception to throw, or a place to catch ParamNotConvertedException and throw NotFoundHttpException when in an HTTP context.
Comment #5
tim.plunkettPer @msonnabaum's suggestion, I tried overriding the RouterListener, and it worked like a charm.
Comment #7
dawehnerI am a bit confused ... the main point of the param converter system is to upcast stuff, which is done in the enhance bit.
I would have argued that setRouteParameterConverters does not really belong on there, because this is the part also couples to the routing system.
In general can we agree that pure internal rewrites should not be "major"?
Comment #9
tim.plunkettComment #10
tim.plunkettOkay, so we (@msonnabaum @Crell and I) talked through this a bunch more, mostly about which parts of this code are which object's responsibility.
The _raw_variables stuff is now part of the enhancer, and it better delegates to the manager.
This should help alleviate @dawehner's concern.
The interdiff is pretty useless IMO, reading the patch is probably easier.
Comment #11
tim.plunkettComment #12
tim.plunkettI accidentally removed the test coverage for #2103145: ParameterConverter mangles raw values, adding that back :)
Comment #13
dawehnerI really like this patch now!
So does that mean that our router does not support something else than HTTP?
This is certainly a progress!
Comment #14
tim.plunkettThe new RouterListener is just enforcing the current assumptions made in HEAD, but moving them out of the router, and into the event subscriber that subscribes to KernelEvents::REQUEST.
It's not actually the RouterListener, but the RouterRequestSubscriber...
But that's now our naming, it's from Symfony.
Comment #15
dawehnerIt feels wrong that out RouterListener is aware of the ParamConverter, which is a subsystem that extending the router horizontally. Usually the param converter manager throws its exception because it is/was a route enhancer. Can't we achieve that by not hardcoding that into our RouterListener?
A little bit more docs would be nice.
Comment #16
tim.plunkettThankfully @dawehner found a solution: GetResponseForExceptionEvent. It allows us to intercept and swap the exception, but only when from a request. Perfect!
I also improved the exception message for ParamNotConvertedException, and added more docs to ParamConversionEnhancer per #15.2.
Added a proposed commit message, since dawehner has worked through this with me the whole way.
Comment #17
dawehner<3
You don't really need to specify priority 0, but this is not commit-blocking at all.
Comment #18
Crell commentedThe listener is way better than extending the class. Great work!
Comment #19
tim.plunkettI almost started writing a change record called "NotFoundHttpException is never to be used in access checks", and then I realized I was just saying "no really, don't do that thing you were never ever supposed to do".
So I'm skipping that one.
Wrote up https://drupal.org/node/2188259 instead for the new exception.
Comment #20
yesct commentedI read the draft change record, edited it a tiny bit. Made sense to me.
Comment #21
webchickCommitted and pushed to 8.x. Thanks!
Comment #23
ParisLiakos commentedshouldnt the change record be published now? or there are other issues required for that?