Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Not sure if rest.module
is the right component for this issue.
Regardless, \Drupal\Core\Http\Exception\CacheableHttpException
extends Symfony\Component\HttpKernel\Exception\HttpException
. The fourth argument to HttpException
must be an array of headers. CacheableHttpException
instead passes its $code
argument as the fourth value. It should be the fifth.
Patch soon.
Comment | File | Size | Author |
---|---|---|---|
#42 | 3002352-42.patch | 6.77 KB | andypost |
#42 | interdiff.txt | 1.57 KB | andypost |
Comments
Comment #2
gabesulliceComment #3
borisson_Should we write a test to make sure we don't regress here? Not sure, because it's just a wrong implementation, but seeing as nothing broke in the tests it means that we're not testing this codepath.
Comment #4
longwaveThese cacheable exceptions don't seem to have many test cases but there is one case we can extend to do this.
Comment #5
longwaveOh, this is going to fail because it requires the Allow header to be set, but CacheableHttpException doesn't support this.
Comment #8
longwaveAs HttpException accepts an array of headers I think CacheableHttpException should do the same. This is technically a BC break but as this method has never worked I think this is okay to change here? This means we can also get the new test to pass.
Comment #9
longwaveGoing to add better test coverage instead of piggybacking off that existing test.
Comment #10
longwaveThis patch fixes the issue originally reported and adds some basic test coverage for all the cacheable HTTP exception classes.
Comment #11
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedChanging the order of argument for the CacheableHttpException class will break BC.
We can freely add headers as 5th argument and still keep it as 4th argument in the constructor. Doing so, anybody using this as advised would get benifit of this fix. Not 100% sure what we prefer here as it would be a bit odd to mix args.
Comment #12
longwaveI realise this is a technical BC break but the current constructor just throws an error, so aren't we just allowed to fix it here? I don't see how anyone can be using it in its current state.
The most basic test case, on current 8.7.x:
Comment #13
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedI looked into this.
The exception was introduced 1 year ago and has not been changed since. Back when it was introduced it was breaking as well, meaning no one can use this - so BC should not be an issue.
Drupal has a wide range of specific cacheable http exceptions, like CacheableAccessDeniedHttpException, CacheableBadRequestHttpException etc. Common for all of these, is that the depend on specific symfony counterparts, like AccessDeniedHttpException, BadRequestHttpException etc. The generic HttpException is the only one which allows setting headers. Most likely some one created a bunch of these at the same time, made a c/p error and no one noticed the bug.
I have looked through the patch and the code looks good.
I would like for good measures that you make a test only patch from #10 patch as it's different from the #4 one, so we can validate that it indeed fail as expected.
When you have done this, I would say that this is RTBC. It's really great that you wrote a test for all HTTP exceptions, so we know these wont break again in the future.
Comment #14
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedComment #15
longwaveReuploaded #10 plus a test-only patch.
Comment #16
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedExcellent, assuming we will have a green and red test result, this is RTBC imo.
Comment #17
longwaveComment #18
Wim LeersExcellent, thank you all!
Comment #19
longwaveHa, interesting. Because both the parameters to the original exception and the child exception are wrong, the test case actually passes; the headers are passed through via the incorrect
$code
parameter. So, if we explicitly test the$code
parameter this should actually fail/pass as expected.This does demonstrate that it is technically possible to use this as-is in core, but you have to supply all arguments to the function with an empty array as
$code
if you want no headers, so I hope this is still okay to fix.Comment #20
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedFunny that it actually works when you misuse the arguments in the constructor. I would still argue that this is a bug, and for this to work for anybody, that would most likely use the class the way it's meant to be used after the change and not the way it's currently meant to be used.
I'm going to repeat myself, the change looks good so if we get red + green we are RTBC.
Comment #23
longwaveSpurious fail in a JS test, back to RTBC
Comment #25
longwaveComment #26
alexpottSo yep this is fundamentally broken...
So the question is shouldn't we remove it. AFAICS it has no usages.
Comment #27
alexpottAdding the issue that added the code to #2920001: Add cacheable HTTP exceptions: Symfony HTTP exceptions + Drupal cacheability metadata.
Comment #28
gabesullice@alexpott, while it's not used in core, I do still need it in JSON:API to send a
501 Not Implemented
response that is cacheable byurl.path
and a query arg cache context.Comment #29
alexpottI've also been thinking about the wider issue of class structure here because whilst
CacheableHttpException
is very broken we have a chance to fix it. AtmCacheableAccessDeniedHttpException
inherits fromAccessDeniedHttpException
inherits fromHttpException
. You might expect the class chain to look something likeCacheableAccessDeniedHttpException
->CacheableHttpException
->HttpException
but theninstanceof AccessDeniedException
won't work.I wonder if #28 should be solved by:
CacheableNotImplementedHttpException
and removingCacheableHttpException
CacheableHttpException
toCacheableGenericHttpException
so it doesn't look so much like the base class it's not.Comment #35
andypostNeeds to check that headers are required or not in context of #3224420-6: [PHP 8.1] Exception codes should be numeric and not NULL
Comment #36
andypostConfirm that current jsonapi codebase (which came from contrib http://grep.xnddx.ru/search?text=CacheableHttpException) passing
[]
instead of$code
which defined?int $code = 0
in SymfonyComment #37
daffie CreditAttribution: daffie commented#3224420: [PHP 8.1] Exception codes should be numeric and not NULL has landed.
Comment #38
andypostre-roll
Comment #40
andypostFix calling code
Comment #41
longwaveShould we remove the NULL as well, as it's the default value of $previous?
Comment #42
andypostGood point! Thank you
Comment #43
daffie CreditAttribution: daffie commentedI do not understand why this code is added to this patch. This is out of scope for this issue. Could we move this to a followup?
Can we add a dataProvider method, so that we can test the exception with different kind of parameter values.
Comment #44
longwave#43.1 there are no tests for any of these cacheable HTTP exceptions so to me it made sense to add tests all at once.
#43.2 what sort of values would you want in a data provider? The constructor we are testing is only two lines and the superclass belongs to Symfony; I am not sure what value there is in trying different arguments.
Comment #45
daffie CreditAttribution: daffie commentedFor #29: Maybe we should do that in a followup. We are here fixing a bug.
For #43.1: I still think that it is a bit out of scope, but is only adds testing. So lets add it.
For #43.2: I was a bit worried about calling the exception with its firth parameter being an integer. Only that change has been added in 9.3 and we are still in 9.3, therefor we can change it without it being a BC break.
The bug is fixed and testing has been added.
We can fix it in 9.3 without creating a BC break.
For me it is RTBC.
Comment #46
catchWhat happens if contrib is doing this? Do we need a bc layer in the constructor for when $code is passed explicitly?
Comment #47
daffie CreditAttribution: daffie commentedI do not think we need a BC layer:
We can change this in 9.3 as long as 9.3.0 is not released, without it being a BC break.
Comment #49
catchBoth good points.
Committed 5cd5a9d and pushed to 9.3.x. Thanks!