From e0a8d33711a7540e1a9fb6855ca2c8e106130255 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Fri, 23 Aug 2019 11:42:49 +0100
Subject: [PATCH] Issue #3052954 by Wim Leers, gabesullice, garphy: Incorrect
 use of UnprocessableHttpEntityException in EntityResource::deserialize()

---
 .../jsonapi/src/Controller/EntityResource.php |  6 ++--
 .../src/Functional/JsonApiRegressionTest.php  | 32 +++++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/core/modules/jsonapi/src/Controller/EntityResource.php b/core/modules/jsonapi/src/Controller/EntityResource.php
index 5c43d3ee24e7..8c0e027aa32d 100644
--- a/core/modules/jsonapi/src/Controller/EntityResource.php
+++ b/core/modules/jsonapi/src/Controller/EntityResource.php
@@ -30,7 +30,6 @@
 use Drupal\jsonapi\Entity\EntityValidationTrait;
 use Drupal\jsonapi\Access\TemporaryQueryGuard;
 use Drupal\jsonapi\Exception\EntityAccessDeniedHttpException;
-use Drupal\jsonapi\Exception\UnprocessableHttpEntityException;
 use Drupal\jsonapi\IncludeResolver;
 use Drupal\jsonapi\JsonApiResource\IncludedData;
 use Drupal\jsonapi\JsonApiResource\LinkCollection;
@@ -53,6 +52,7 @@
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Drupal\Core\Http\Exception\CacheableBadRequestHttpException;
 use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
+use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
 use Symfony\Component\Serializer\Exception\InvalidArgumentException;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 use Symfony\Component\Serializer\SerializerInterface;
@@ -822,10 +822,10 @@ protected function deserialize(ResourceType $resource_type, Request $request, $c
     // These two serialization exception types mean there was a problem with
     // the structure of the decoded data and it's not valid.
     catch (UnexpectedValueException $e) {
-      throw new UnprocessableHttpEntityException($e->getMessage());
+      throw new UnprocessableEntityHttpException($e->getMessage());
     }
     catch (InvalidArgumentException $e) {
-      throw new UnprocessableHttpEntityException($e->getMessage());
+      throw new UnprocessableEntityHttpException($e->getMessage());
     }
   }
 
diff --git a/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php b/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
index 636e8d141f33..3fc3c5a183d9 100644
--- a/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
@@ -1053,4 +1053,36 @@ public function testNonTranslatableEntityUpdatesFromIssue3043168() {
     $this->assertSame('Constantine', $response_document['data']['attributes']['name']);
   }
 
+  /**
+   * Ensure POSTing invalid data results in a 422 response, not a PHP error.
+   *
+   * @see https://www.drupal.org/project/drupal/issues/3052954
+   */
+  public function testInvalidDataTriggersUnprocessableEntityErrorFromIssue3052954() {
+    $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
+
+    // Set up data model.
+    $user = $this->drupalCreateUser(['bypass node access']);
+
+    // Test.
+    $request_options = [
+      RequestOptions::HEADERS => [
+        'Content-Type' => 'application/vnd.api+json',
+        'Accept' => 'application/vnd.api+json',
+      ],
+      RequestOptions::JSON => [
+        'data' => [
+          'type' => 'article',
+          'attributes' => [
+            'title' => 'foobar',
+            'created' => 'not_a_date',
+          ],
+        ],
+      ],
+      RequestOptions::AUTH => [$user->getAccountName(), $user->pass_raw],
+    ];
+    $response = $this->request('POST', Url::fromUri('internal:/jsonapi/node/article'), $request_options);
+    $this->assertSame(422, $response->getStatusCode());
+  }
+
 }
-- 
GitLab