Discovered while working on #2930028: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only.

From #2930028-9: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only's test results:

--- Expected
+++ Actual
@@ @@
-{"errors":[{"title":"Unprocessable Entity","status":422,"detail":"Unprocessable Entity: validation failed.\ntitle: Title: this field cannot hold more than 1 values.\n","links":{"info":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html"},"code":0}]}
+{"errors":[{"title":"Unprocessable Entity","status":422,"detail":"There was an error un-serializing the data. Message: Deserialization for the format  is not supported","links":{"info":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html"},"code":0}]}

That is directly caused by \Drupal\jsonapi\Controller\RequestHandler::deserializeBody() doing this:

    $format = $request->getContentType();
…
    try {
      return $serializer->deserialize($received, $serialization_class, $format, [
…      ]);
    }

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new1021 bytes

#2934149: [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX would've solved the root cause, and would've resulted in this not mattering, but there nevertheless is no point in making this dynamic when we can just hardcode it to api_json.

wim leers’s picture

StatusFileSize
new1.22 KB
new2.2 KB

So this is apparently breaking an existing JSON API test. That test does:

    // 3. Missing Content-Type error.
    $response = $this->request('POST', $collection_url, [
      'body' => Json::encode($body),
      'auth' => [$this->user->getUsername(), $this->user->pass_raw],
      'headers' => ['Accept' => 'application/vnd.api+json'],
    ]);
    $created_response = Json::decode($response->getBody()->__toString());
    $this->assertEquals(422, $response->getStatusCode());
    $this->assertNotEmpty($created_response['errors']);
    $this->assertEquals('Unprocessable Entity', $created_response['errors'][0]['title']);

That looks as if it's testing that there's a helpful error response for a missing Content-Type request header. But the response looks like this:

 array(1) {
  ["errors"]=>
  array(1) {
    [0]=>
    array(5) {
      ["title"]=>
      string(20) "Unprocessable Entity"
      ["status"]=>
      int(422)
      ["detail"]=>
      string(101) "There was an error un-serializing the data. Message: Deserialization for the format  is not supported"
      ["links"]=>
      array(1) {
        ["info"]=>
        string(54) "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"
      }
      ["code"]=>
      int(0)
    }
  }
}

So: Deserialization for the format is not supported — that's not remotely helpful.

The actually helpful error response would be added by #2934149: [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX. I'm commenting this test coverage for now, in favor of #2934149: [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX.

  • Wim Leers committed 4432ebd on 8.x-1.x
    Issue #2934164 by Wim Leers: \Drupal\jsonapi\Controller\RequestHandler::...
wim leers’s picture

Status: Needs review » Fixed
e0ipso’s picture

I agree the error message could be better, but I think it's better than nothing. Let's put the improved version back soon so we don't forget about this.

wim leers’s picture

We won't forget about this, because A) there's a @todo, B) there's an issue that it points to: #2934149: [>=8.5] JSON API routes not specifying _content_type_format route requirement, resulting in bad DX.

Status: Fixed » Closed (fixed)

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