Problem/Motivation

While working on expanding the HTTP POST test coverage in #2737719: EntityResource: Provide comprehensive test coverage: for every entity type, every format, every method, I noticed that when the developer forgets to specify the Content-Type request header that they get this rather cryptic message:

{"message":"No route found that matches \u0022Content-Type: \u0022"}

Those \u0022 should be interpreted as "double quote". So it's repeating the literal Content-Type request header: both the key and its value, and the value just happens to be NULL, which PHP casts to the empty string.

Proposed resolution

Detect when the Content-Type request header is not set and provide a more helpful error response:

No "Content-Type" request header specified.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

Assigned: wim leers » Unassigned
Status: Active » Needs review
StatusFileSize
new1.34 KB
new2.55 KB
wim leers’s picture

dawehner’s picture

  1. +++ b/core/tests/Drupal/Tests/Core/Routing/ContentTypeHeaderMatcherTest.php
    @@ -101,4 +102,21 @@ public function testNoRouteFound() {
    +   * Confirms that the matcher throws an exception for missing request header.
    +   *
    +   * @expectedException \Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException
    +   * @expectedExceptionMessage No "Content-Type" request header specified.
    

    We use setExpectedException() now, see https://thephp.cc/news/2016/02/questioning-phpunit-best-practices. Mh ideally we would have a @covers here

  2. +++ b/core/tests/Drupal/Tests/Core/Routing/ContentTypeHeaderMatcherTest.php
    @@ -101,4 +102,21 @@ public function testNoRouteFound() {
    +    $this->fail('No exception was thrown.');
    

    We really don't need this with set expected exception

wim leers’s picture

#4: all of that is just copy/pasted from the existing test at \Drupal\Tests\Core\Routing\ContentTypeHeaderMatcherTest::testNoRouteFound(). You're okay with me fixing both?

dawehner’s picture

Well, feel free to choose :) I just don't believe in adding bad new code. I know you value consistency more

neclimdul’s picture

Status: Needs review » Needs work

re #5
1) Is new. Megh but it is the new way. If you're going to do it just put it right before the method going to throw the exception so you test only the method you're testing not some other code that might have thrown the exception.

2) Well ContentTypeHeaderMatcherTest is wrong then. fail() will bypass the expected exception expectations because it runs after the test method finishes. This means the failure message doesn't include the exception type unless it throws the wrong exception type.

wim leers’s picture

Agreed. So let's fix both then.

dawehner’s picture

1) Is new. Megh but it is the new way. If you're going to do it just put it right before the method going to throw the exception so you test only the method you're testing not some other code that might have thrown the exception.

Yeah exactly, its also describing for users where the exception is thrown. All in all just improvements.

all of that is just copy/pasted from the existing test at

Everytime someone comes up with that, similar (it would not be worth to test), its suspicious :P

neclimdul’s picture

Status: Needs work » Needs review
StatusFileSize
new2.55 KB
new3.38 KB

Is this what we're looking for?

neclimdul’s picture

Also writing this I found it interesting that one of these 2 exception messages has a period and one doesn't. I don't actually know what our standard is for such things.

wim leers’s picture

#11: yes!

I would RTBC but there's still #12. I don't care either way, but the pedant in me screams period!.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

I personally don't care about the dots :) The discussion might better end up in its own issue + a fix for all the exception messages.

wim leers’s picture

+1

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 97f0d43 and pushed to 8.3.x. Thanks!

Also I think this is actually a bug and should be backported to 8.2.x - but I'll leave that to those on the issue to decide.

diff --git a/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php b/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php
index 973037b..13e18f3 100644
--- a/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php
+++ b/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php
@@ -43,7 +43,7 @@ public function filter(RouteCollection $collection, Request $request) {
     // \Symfony\Component\Routing\Exception\ResourceNotFoundException here
     // because we don't want to return a 404 status code, but rather a 415.
     if (!$request->headers->has('Content-Type')) {
-      throw new UnsupportedMediaTypeHttpException('No "Content-Type" request header specified.');
+      throw new UnsupportedMediaTypeHttpException('No "Content-Type" request header specified');
     }
     else {
       throw new UnsupportedMediaTypeHttpException('No route found that matches "Content-Type: ' . $request->headers->get('Content-Type') . '"');

Remove dot on commit for consistency. Also we've already discussed and agreed no dots.

  • alexpott committed 97f0d43 on 8.3.x
    Issue #2811133 by Wim Leers, neclimdul, dawehner: Confusing error...

  • catch committed b104e87 on 8.3.x
    Revert "Issue #2811133 by Wim Leers, neclimdul, dawehner: Confusing...
catch’s picture

Status: Fixed » Needs work

This broke 8.3.x tests: https://www.drupal.org/pift-ci-job/503665

Rolled back for now. Late here so didn't look into why.

cilefen’s picture

Status: Needs work » Needs review
StatusFileSize
new880 bytes
new3.38 KB

For me, it's the period, but weird.

cilefen’s picture

StatusFileSize
new1.59 KB
new3.38 KB

Oh, it's simple. #16 removed the period from the logic but not from the test.

catch’s picture

Status: Needs review » Reviewed & tested by the community

That'd do it!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Okay alexpott--

As per #16

Also I think this is actually a bug and should be backported to 8.2.x - but I'll leave that to those on the issue to decide.

Committed 8bbdbed and pushed to 8.3.x. Thanks!

  • alexpott committed 8bbdbed on 8.3.x
    Issue #2811133 by cilefen, Wim Leers, neclimdul, dawehner: Confusing...
wim leers’s picture

Status: Fixed » Patch (to be ported)

Also I think this is actually a bug and should be backported to 8.2.x - but I'll leave that to those on the issue to decide.

+1

alexpott’s picture

Status: Patch (to be ported) » Fixed

Discussed with a @catch and we both agreed this is fine for 8.2.x

Committed 4d97701 and pushed to 8.2.x. Thanks!

  • alexpott committed 4d97701 on 8.2.x
    Issue #2811133 by cilefen, Wim Leers, neclimdul, dawehner: Confusing...
wim leers’s picture

Yay! Better DX for 8.2!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.