 jsonapi.services.yml                               |  5 --
 src/Context/FieldResolver.php                      |  8 +--
 src/Error/ErrorHandler.php                         |  4 +-
 src/Error/SerializableHttpException.php            | 12 -----
 src/EventSubscriber/DefaultExceptionSubscriber.php | 60 ----------------------
 src/LinkManager/LinkManager.php                    |  4 +-
 src/Normalizer/EntityNormalizer.php                |  4 +-
 src/Normalizer/EntityReferenceFieldNormalizer.php  | 11 ++--
 src/Query/QueryBuilder.php                         |  4 +-
 src/RequestHandler.php                             |  5 +-
 src/Resource/EntityResource.php                    | 44 ++++++++--------
 src/ResourceResponse.php                           |  6 +++
 src/Routing/Param/Filter.php                       |  5 +-
 src/Routing/Param/OffsetPage.php                   |  5 +-
 src/Routing/Param/Sort.php                         |  9 ++--
 src/Routing/RouteEnhancer.php                      |  4 +-
 16 files changed, 62 insertions(+), 128 deletions(-)

diff --git a/jsonapi.services.yml b/jsonapi.services.yml
index b7bc7c6..cf255d0 100644
--- a/jsonapi.services.yml
+++ b/jsonapi.services.yml
@@ -94,8 +94,3 @@ services:
   plugin.manager.resource.processor:
     class: Drupal\jsonapi\Plugin\JsonApiResourceManager
     parent: default_plugin_manager
-  jsonapi.exception_subscriber:
-    class: Drupal\jsonapi\EventSubscriber\DefaultExceptionSubscriber
-    tags:
-      - { name: event_subscriber }
-    arguments: ['@serializer', '%serializer.formats%']
diff --git a/src/Context/FieldResolver.php b/src/Context/FieldResolver.php
index e9e17d6..108ecde 100644
--- a/src/Context/FieldResolver.php
+++ b/src/Context/FieldResolver.php
@@ -3,7 +3,7 @@
 namespace Drupal\jsonapi\Context;
 
 use Drupal\Core\Entity\EntityFieldManagerInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 
 /**
  * Contains FieldResolver.
@@ -52,7 +52,7 @@ class FieldResolver implements FieldResolverInterface {
    */
   public function resolveInternal($external_field_name) {
     if (empty($external_field_name)) {
-      throw new SerializableHttpException(400, 'No field name was provided for the filter.');
+      throw new BadRequestHttpException('No field name was provided for the filter.');
     }
     // Right now we are exposing all the fields with the name they have in
     // the Drupal backend. But this may change in the future.
@@ -68,13 +68,13 @@ class FieldResolver implements FieldResolverInterface {
     $entity_type_id = $this->currentContext->getResourceConfig()->getEntityTypeId();
     foreach ($parts as $field_name) {
       if (!$definitions = $this->fieldManager->getFieldStorageDefinitions($entity_type_id)) {
-        throw new SerializableHttpException(400, sprintf('Invalid nested filtering. There is no entity type "%s".', $entity_type_id));
+        throw new BadRequestHttpException(sprintf('Invalid nested filtering. There is no entity type "%s".', $entity_type_id));
       }
       if (
         empty($definitions[$field_name]) ||
         $definitions[$field_name]->getType() != 'entity_reference'
       ) {
-        throw new SerializableHttpException(400, sprintf('Invalid nested filtering. Invalid entity reference "%s".', $field_name));
+        throw new BadRequestHttpException(sprintf('Invalid nested filtering. Invalid entity reference "%s".', $field_name));
       }
       // Update the entity type with the referenced type.
       $entity_type_id = $definitions[$field_name]->getSetting('target_type');
diff --git a/src/Error/ErrorHandler.php b/src/Error/ErrorHandler.php
index 9e13560..c57fc33 100644
--- a/src/Error/ErrorHandler.php
+++ b/src/Error/ErrorHandler.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\jsonapi\Error;
 
+use Symfony\Component\HttpKernel\Exception\HttpException;
+
 class ErrorHandler extends ErrorHandlerBase {
 
   /**
@@ -14,7 +16,7 @@ class ErrorHandler extends ErrorHandlerBase {
     list($severity_msg, $severity_level) = $types[$error_level];
     // Only halt execution if the error is more severe than a warning.
     if ($severity_level < 4) {
-      throw new SerializableHttpException(500, sprintf('[%s] %s', $severity_msg, $message), NULL, [], $error_level);
+      throw new HttpException(500, sprintf('[%s] %s', $severity_msg, $message), NULL, [], $error_level);
     }
   }
 
diff --git a/src/Error/SerializableHttpException.php b/src/Error/SerializableHttpException.php
deleted file mode 100644
index a4ae814..0000000
--- a/src/Error/SerializableHttpException.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\jsonapi\Error;
-
-use Drupal\Core\DependencyInjection\DependencySerializationTrait;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-
-class SerializableHttpException extends HttpException {
-
-  use DependencySerializationTrait;
-
-}
diff --git a/src/EventSubscriber/DefaultExceptionSubscriber.php b/src/EventSubscriber/DefaultExceptionSubscriber.php
deleted file mode 100644
index f54f6d5..0000000
--- a/src/EventSubscriber/DefaultExceptionSubscriber.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-
-namespace Drupal\jsonapi\EventSubscriber;
-
-use Drupal\jsonapi\Error\SerializableHttpException;
-use Drupal\serialization\EventSubscriber\DefaultExceptionSubscriber as SerializationDefaultExceptionSubscriber;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-
-class DefaultExceptionSubscriber extends SerializationDefaultExceptionSubscriber {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static function getPriority() {
-    return parent::getPriority() + 25;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getHandledFormats() {
-    return ['api_json'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function onException(GetResponseForExceptionEvent $event) {
-    /** @var \Symfony\Component\HttpKernel\Exception\HttpException $exception */
-    $exception = $event->getException();
-    $format = $event->getRequest()->getRequestFormat();
-    if (!$this->serializer->supportsEncoding($format)) {
-      return;
-    }
-    if (!$exception instanceof HttpException) {
-      $exception = new SerializableHttpException(500, $exception->getMessage(), $exception);
-      $event->setException($exception);
-    }
-
-    $this->setEventResponse($event, $exception->getStatusCode());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setEventResponse(GetResponseForExceptionEvent $event, $status) {
-    /** @var \Symfony\Component\HttpKernel\Exception\HttpException $exception */
-    $exception = $event->getException();
-    $format = $event->getRequest()->getRequestFormat();
-    if (!$this->serializer->supportsNormalization($exception, $format)) {
-      return;
-    }
-    $encoded_content = $this->serializer->serialize($exception, $format, ['data_wrapper' => 'errors']);
-    $response = new Response($encoded_content, $status);
-    $event->setResponse($response);
-  }
-
-}
diff --git a/src/LinkManager/LinkManager.php b/src/LinkManager/LinkManager.php
index d524d9c..f1ce4c0 100644
--- a/src/LinkManager/LinkManager.php
+++ b/src/LinkManager/LinkManager.php
@@ -4,10 +4,10 @@ namespace Drupal\jsonapi\LinkManager;
 
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\jsonapi\Configuration\ResourceConfigInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\Routing\Param\OffsetPage;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
 
 /**
@@ -86,7 +86,7 @@ class LinkManager implements LinkManagerInterface {
       $size = OffsetPage::$maxSize;
     }
     if ($size <= 0) {
-      throw new SerializableHttpException(400, sprintf('The page size needs to be a positive integer.'));
+      throw new BadRequestHttpException(sprintf('The page size needs to be a positive integer.'));
     }
     $query = (array) $request->query->getIterator();
     $links = [];
diff --git a/src/Normalizer/EntityNormalizer.php b/src/Normalizer/EntityNormalizer.php
index eefd8f7..c370b28 100644
--- a/src/Normalizer/EntityNormalizer.php
+++ b/src/Normalizer/EntityNormalizer.php
@@ -8,10 +8,10 @@ use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Field\EntityReferenceFieldItemList;
 use Drupal\jsonapi\Configuration\ResourceConfigInterface;
 use Drupal\jsonapi\Context\CurrentContextInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\LinkManager\LinkManagerInterface;
 use Drupal\jsonapi\Normalizer\Value\NullFieldNormalizerValue;
 use Drupal\jsonapi\RelationshipInterface;
+use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
 use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 
 /**
@@ -130,7 +130,7 @@ class EntityNormalizer extends NormalizerBase implements DenormalizerInterface,
    */
   public function denormalize($data, $class, $format = NULL, array $context = array()) {
     if (empty($context['resource_config']) || !$context['resource_config'] instanceof ResourceConfigInterface) {
-      throw new SerializableHttpException(412, 'Missing context during denormalization.');
+      throw new PreconditionFailedHttpException('Missing context during denormalization.');
     }
     /* @var \Drupal\jsonapi\Configuration\ResourceConfigInterface $resource_config */
     $resource_config = $context['resource_config'];
diff --git a/src/Normalizer/EntityReferenceFieldNormalizer.php b/src/Normalizer/EntityReferenceFieldNormalizer.php
index 855ac04..50662fe 100644
--- a/src/Normalizer/EntityReferenceFieldNormalizer.php
+++ b/src/Normalizer/EntityReferenceFieldNormalizer.php
@@ -8,7 +8,6 @@ use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
 use Drupal\jsonapi\Configuration\ResourceManagerInterface;
 use Drupal\jsonapi\EntityCollection;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\LinkManager\LinkManagerInterface;
 use Drupal\jsonapi\Relationship;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -95,7 +94,7 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
       $context['resource_config']->getBundleId()
     );
     if (empty($context['related']) || empty($field_definitions[$context['related']])) {
-      throw new SerializableHttpException(400, 'Invalid or missing related field.');
+      throw new BadRequestHttpException('Invalid or missing related field.');
     }
     /* @var \Drupal\field\Entity\FieldConfig $field_definition */
     $field_definition = $field_definitions[$context['related']];
@@ -110,7 +109,7 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
       // Make sure that the provided type is compatible with the targeted
       // resource.
       if (!in_array($value['type'], $target_resources)) {
-        throw new SerializableHttpException(400, sprintf(
+        throw new BadRequestHttpException(sprintf(
           'The provided type (%s) does not mach the destination resource types (%s).',
           $value['type'],
           implode(', ', $target_resources)
@@ -136,14 +135,14 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
   protected function massageRelationshipInput($data, $is_multiple) {
     if ($is_multiple) {
       if (!is_array($data['data'])) {
-        throw new SerializableHttpException(400, 'Invalid body payload for the relationship.');
+        throw new BadRequestHttpException('Invalid body payload for the relationship.');
       }
       // Leave the invalid elements.
       $invalid_elements = array_filter($data['data'], function ($element) {
         return empty($element['type']) || empty($element['id']);
       });
       if ($invalid_elements) {
-        throw new SerializableHttpException(400, 'Invalid body payload for the relationship.');
+        throw new BadRequestHttpException('Invalid body payload for the relationship.');
       }
     }
     else {
@@ -152,7 +151,7 @@ class EntityReferenceFieldNormalizer extends FieldNormalizer implements Denormal
         return ['data' => []];
       }
       if (empty($data['data']['type']) || empty($data['data']['id'])) {
-        throw new SerializableHttpException(400, 'Invalid body payload for the relationship.');
+        throw new BadRequestHttpException('Invalid body payload for the relationship.');
       }
       $data['data'] = [$data['data']];
     }
diff --git a/src/Query/QueryBuilder.php b/src/Query/QueryBuilder.php
index 3d3dfce..b98d336 100644
--- a/src/Query/QueryBuilder.php
+++ b/src/Query/QueryBuilder.php
@@ -4,7 +4,6 @@ namespace Drupal\jsonapi\Query;
 
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\Routing\Param\OffsetPage;
 use Drupal\jsonapi\Routing\Param\Filter;
 use Drupal\jsonapi\Routing\Param\JsonApiParamInterface;
@@ -163,8 +162,7 @@ class QueryBuilder implements QueryBuilderInterface {
             break;
 
           default:
-            throw new SerializableHttpException(
-              400,
+            throw new BadRequestHttpException(
               sprintf('Invalid syntax in the filter parameter: %s.', $filter_index)
             );
         };
diff --git a/src/RequestHandler.php b/src/RequestHandler.php
index bef31ab..47a3f18 100644
--- a/src/RequestHandler.php
+++ b/src/RequestHandler.php
@@ -7,13 +7,13 @@ use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\jsonapi\Context\CurrentContextInterface;
 use Drupal\jsonapi\Error\ErrorHandlerInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\Resource\EntityResource;
 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 use Symfony\Component\Serializer\SerializerInterface;
@@ -186,8 +186,7 @@ class RequestHandler implements ContainerAwareInterface, ContainerInjectionInter
       ]);
     }
     catch (UnexpectedValueException $e) {
-      throw new SerializableHttpException(
-        422,
+      throw new UnprocessableEntityHttpException(
         sprintf('There was an error un-serializing the data. Message: %s.', $e->getMessage()),
         $e
       );
diff --git a/src/Resource/EntityResource.php b/src/Resource/EntityResource.php
index fd62d0f..afc3634 100644
--- a/src/Resource/EntityResource.php
+++ b/src/Resource/EntityResource.php
@@ -17,7 +17,6 @@ use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\jsonapi\Configuration\ResourceConfigInterface;
 use Drupal\jsonapi\EntityCollection;
 use Drupal\jsonapi\EntityCollectionInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Drupal\jsonapi\Query\QueryBuilderInterface;
 use Drupal\jsonapi\Context\CurrentContextInterface;
 use Drupal\jsonapi\ResourceResponse;
@@ -25,6 +24,11 @@ use Drupal\jsonapi\Routing\Param\JsonApiParamBase;
 use Drupal\jsonapi\Routing\Param\OffsetPage;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
 
 /**
  * Class EntityResource.
@@ -106,7 +110,7 @@ class EntityResource implements EntityResourceInterface {
   public function getIndividual(EntityInterface $entity, Request $request, $response_code = 200) {
     $entity_access = $entity->access('view', NULL, TRUE);
     if (!$entity_access->isAllowed()) {
-      throw new SerializableHttpException(403, 'The current user is not allowed to GET the selected resource.');
+      throw new AccessDeniedHttpException('The current user is not allowed to GET the selected resource.');
     }
     $response = $this->buildWrappedResponse($entity, $response_code);
     return $response;
@@ -141,7 +145,7 @@ class EntityResource implements EntityResourceInterface {
       // 422 Unprocessable Entity code from RFC 4918. That way clients can
       // distinguish between general syntax errors in bad serializations (code
       // 400) and semantic errors in well-formed requests (code 422).
-      throw new SerializableHttpException(422, $message);
+      throw new UnprocessableEntityHttpException($message);
     }
   }
 
@@ -152,7 +156,7 @@ class EntityResource implements EntityResourceInterface {
     $entity_access = $entity->access('create', NULL, TRUE);
 
     if (!$entity_access->isAllowed()) {
-      throw new SerializableHttpException(403, 'The current user is not allowed to POST the selected resource.');
+      throw new AccessDeniedHttpException('The current user is not allowed to POST the selected resource.');
     }
     $this->validate($entity);
     $entity->save();
@@ -165,13 +169,13 @@ class EntityResource implements EntityResourceInterface {
   public function patchIndividual(EntityInterface $entity, EntityInterface $parsed_entity, Request $request) {
     $entity_access = $entity->access('update', NULL, TRUE);
     if (!$entity_access->isAllowed()) {
-      throw new SerializableHttpException(403, 'The current user is not allowed to GET the selected resource.');
+      throw new AccessDeniedHttpException('The current user is not allowed to GET the selected resource.');
     }
     $body = Json::decode($request->getContent());
     $data = $body['data'];
     $id_key = $this->resourceConfig->getIdKey();
     if (!method_exists($entity, $id_key) || $data['id'] != $entity->{$id_key}()) {
-      throw new SerializableHttpException(400, sprintf(
+      throw new BadRequestHttpException(sprintf(
         'The selected entity (%s) does not match the ID in the payload (%s).',
         $entity->{$id_key}(),
         $data['id']
@@ -195,7 +199,7 @@ class EntityResource implements EntityResourceInterface {
   public function deleteIndividual(EntityInterface $entity, Request $request) {
     $entity_access = $entity->access('delete', NULL, TRUE);
     if (!$entity_access->isAllowed()) {
-      throw new SerializableHttpException(403, 'The current user is not allowed to DELETE the selected resource.');
+      throw new AccessDeniedHttpException(403, 'The current user is not allowed to DELETE the selected resource.');
     }
     $entity->delete();
     return new ResourceResponse(NULL, 204);
@@ -245,7 +249,7 @@ class EntityResource implements EntityResourceInterface {
   public function getRelated(EntityInterface $entity, $related_field, Request $request) {
     /* @var $field_list \Drupal\Core\Field\FieldItemListInterface */
     if (!($field_list = $entity->get($related_field)) || !$this->isRelationshipField($field_list)) {
-      throw new SerializableHttpException(404, sprintf('The relationship %s is not present in this resource.', $related_field));
+      throw new NotFoundHttpException(sprintf('The relationship %s is not present in this resource.', $related_field));
     }
     $data_definition = $field_list->getDataDefinition();
     // TODO: Also check for access in the related.
@@ -268,7 +272,7 @@ class EntityResource implements EntityResourceInterface {
    */
   public function getRelationship(EntityInterface $entity, $related_field, Request $request, $response_code = 200) {
     if (!($field_list = $entity->get($related_field)) || !$this->isRelationshipField($field_list)) {
-      throw new SerializableHttpException(404, sprintf('The relationship %s is not present in this resource.', $related_field));
+      throw new NotFoundHttpException(sprintf('The relationship %s is not present in this resource.', $related_field));
     }
     $response = $this->buildWrappedResponse($field_list, $response_code);
     return $response;
@@ -293,12 +297,12 @@ class EntityResource implements EntityResourceInterface {
       ->getFieldStorageDefinition()
       ->isMultiple();
     if (!$is_multiple) {
-      throw new SerializableHttpException(409, sprintf('You can only POST to to-many relationships. %s is a to-one relationship.', $related_field));
+      throw new ConflictHttpException(sprintf('You can only POST to to-many relationships. %s is a to-one relationship.', $related_field));
     }
 
     $field_access = $field_list->access('update', NULL, TRUE);
     if (!$field_access->isAllowed()) {
-      throw new SerializableHttpException(403, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_list->getName()));
+      throw new AccessDeniedHttpException(sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_list->getName()));
     }
     // Time to save the relationship.
     foreach ($parsed_field_list as $field_item) {
@@ -345,7 +349,7 @@ class EntityResource implements EntityResourceInterface {
    */
   protected function doPatchIndividualRelationship(EntityInterface $entity, EntityReferenceFieldItemListInterface $parsed_field_list) {
     if ($parsed_field_list->count() > 1) {
-      throw new SerializableHttpException(400, sprintf('Provide a single relationship so to-one relationship fields (%s).', $parsed_field_list->getName()));
+      throw new BadRequestHttpException(sprintf('Provide a single relationship so to-one relationship fields (%s).', $parsed_field_list->getName()));
     }
     $this->doPatchMultipleRelationship($entity, $parsed_field_list);
   }
@@ -363,7 +367,7 @@ class EntityResource implements EntityResourceInterface {
     $field_name = $parsed_field_list->getName();
     $field_access = $parsed_field_list->access('update', NULL, TRUE);
     if (!$field_access->isAllowed()) {
-      throw new SerializableHttpException(403, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name));
+      throw new AccessDeniedHttpException(sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name));
     }
     $entity->{$field_name} = $parsed_field_list;
   }
@@ -383,7 +387,7 @@ class EntityResource implements EntityResourceInterface {
     $field_name = $parsed_field_list->getName();
     $field_access = $parsed_field_list->access('delete', NULL, TRUE);
     if (!$field_access->isAllowed()) {
-      throw new SerializableHttpException(403, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name));
+      throw new AccessDeniedHttpException(sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name));
     }
     /* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field_list */
     $field_list = $entity->{$related_field};
@@ -498,10 +502,10 @@ class EntityResource implements EntityResourceInterface {
     /* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $parsed_field_list */
     $entity_access = $entity->access('update', NULL, TRUE);
     if (!$entity_access->isAllowed()) {
-      throw new SerializableHttpException(403, 'The current user is not allowed to POST the selected resource.');
+      throw new AccessDeniedHttpException('The current user is not allowed to POST the selected resource.');
     }
     if (!($field_list = $entity->get($related_field)) || !$this->isRelationshipField($field_list)) {
-      throw new SerializableHttpException(404, sprintf('The relationship %s is not present in this resource.', $related_field));
+      throw new NotFoundHttpException(sprintf('The relationship %s is not present in this resource.', $related_field));
     }
   }
 
@@ -520,11 +524,11 @@ class EntityResource implements EntityResourceInterface {
     if ($origin instanceof ContentEntityInterface && $destination instanceof ContentEntityInterface) {
       // First scenario: both are content entities.
       if (!$field_list = $destination->get($field_name)) {
-        throw new SerializableHttpException(400, sprintf('The provided field (%s) does not exist in the entity with ID %d.', $field_name, $destination->id()));
+        throw new BadRequestHttpException(sprintf('The provided field (%s) does not exist in the entity with ID %d.', $field_name, $destination->id()));
       }
       $field_access = $field_list->access('update', NULL, TRUE);
       if (!$field_access->isAllowed()) {
-        throw new SerializableHttpException(403, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_list->getName()));
+        throw new AccessDeniedHttpException(sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_list->getName()));
       }
       $destination->{$field_name} = $origin->get($field_name);
     }
@@ -533,7 +537,7 @@ class EntityResource implements EntityResourceInterface {
       $destination->set($field_name, $origin->get($field_name));
     }
     else {
-      throw new SerializableHttpException(400, 'The serialized entity and the destination entity are of different types.');
+      throw new BadRequestHttpException('The serialized entity and the destination entity are of different types.');
     }
   }
 
@@ -577,7 +581,7 @@ class EntityResource implements EntityResourceInterface {
       ];
       if ($entity instanceof AccessibleInterface && !$access->isAllowed()) {
         // Pass an exception to the list of things to normalize.
-        $collection_data[$entity->id()]['entity'] = new SerializableHttpException(403, sprintf(
+        $collection_data[$entity->id()]['entity'] = new AccessDeniedHttpException(sprintf(
           'Access checks failed for entity %s:%s.',
           $entity->getEntityTypeId(),
           $entity->id()
diff --git a/src/ResourceResponse.php b/src/ResourceResponse.php
index 319f705..3e5f31d 100644
--- a/src/ResourceResponse.php
+++ b/src/ResourceResponse.php
@@ -52,4 +52,10 @@ class ResourceResponse extends Response implements CacheableResponseInterface, R
     return $this->responseData;
   }
 
+  // @todo needs proper solution
+  public function __sleep() {
+    $this->responseData = NULL;
+    return array_keys(get_object_vars($this));
+  }
+
 }
diff --git a/src/Routing/Param/Filter.php b/src/Routing/Param/Filter.php
index 8e37f10..258b5a7 100644
--- a/src/Routing/Param/Filter.php
+++ b/src/Routing/Param/Filter.php
@@ -1,7 +1,8 @@
 <?php
 
 namespace Drupal\jsonapi\Routing\Param;
-use Drupal\jsonapi\Error\SerializableHttpException;
+
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 
 /**
  * Class Filter.
@@ -63,7 +64,7 @@ class Filter extends JsonApiParamBase {
   protected function expand() {
     // We should always get an array for the filter.
     if (!is_array($this->original)) {
-      throw new SerializableHttpException(400, 'Incorrect value passed to the filter parameter.');
+      throw new BadRequestHttpException('Incorrect value passed to the filter parameter.');
     }
 
     $expanded = [];
diff --git a/src/Routing/Param/OffsetPage.php b/src/Routing/Param/OffsetPage.php
index 4ae43c4..a10e354 100644
--- a/src/Routing/Param/OffsetPage.php
+++ b/src/Routing/Param/OffsetPage.php
@@ -1,7 +1,8 @@
 <?php
 
 namespace Drupal\jsonapi\Routing\Param;
-use Drupal\jsonapi\Error\SerializableHttpException;
+
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 
 /**
  * Class Page.
@@ -43,7 +44,7 @@ class OffsetPage extends JsonApiParamBase {
    */
   protected function expand() {
     if (!is_array($this->original)) {
-      throw new SerializableHttpException(400, 'The page parameter needs to be an array.');
+      throw new BadRequestHttpException('The page parameter needs to be an array.');
     }
     $output = $this->original + ['size' => static::$maxSize];
     $output['size'] = $output['size'] > static::$maxSize ?
diff --git a/src/Routing/Param/Sort.php b/src/Routing/Param/Sort.php
index a644d68..4509475 100644
--- a/src/Routing/Param/Sort.php
+++ b/src/Routing/Param/Sort.php
@@ -1,7 +1,8 @@
 <?php
 
 namespace Drupal\jsonapi\Routing\Param;
-use Drupal\jsonapi\Error\SerializableHttpException;
+
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 
 /**
  * Class Sort.
@@ -49,7 +50,7 @@ class Sort extends JsonApiParamBase {
     $sort = $this->original;
 
     if (empty($sort)) {
-      throw new SerializableHttpException(400, 'You need to provide a value for the sort parameter.');
+      throw new BadRequestHttpException('You need to provide a value for the sort parameter.');
     }
 
     // Expand a JSON API compliant sort into a more expressive sort parameter.
@@ -110,7 +111,7 @@ class Sort extends JsonApiParamBase {
     ];
 
     if (!isset($sort_item[static::FIELD_KEY])) {
-      throw new SerializableHttpException(400, 'You need to provide a field name for the sort parameter.');
+      throw new BadRequestHttpException('You need to provide a field name for the sort parameter.');
     }
 
     $expected_keys = [
@@ -123,7 +124,7 @@ class Sort extends JsonApiParamBase {
 
     // Verify correct sort keys.
     if (count(array_diff($expected_keys, array_keys($expanded))) > 0) {
-      throw new SerializableHttpException(400, 'You have provided an invalid set of sort keys.');
+      throw new BadRequestHttpException('You have provided an invalid set of sort keys.');
     }
 
     return $expanded;
diff --git a/src/Routing/RouteEnhancer.php b/src/Routing/RouteEnhancer.php
index ca6b5c5..352e7e1 100644
--- a/src/Routing/RouteEnhancer.php
+++ b/src/Routing/RouteEnhancer.php
@@ -3,9 +3,9 @@
 namespace Drupal\jsonapi\Routing;
 
 use Drupal\Core\Routing\Enhancer\RouteEnhancerInterface;
-use Drupal\jsonapi\Error\SerializableHttpException;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -37,7 +37,7 @@ class RouteEnhancer implements RouteEnhancerInterface {
       // If the bundle in the loaded entity does not match the bundle in the
       // route configuration (that comes from the resource_config), then throw
       // an exception.
-      throw new SerializableHttpException(404, sprintf('The loaded entity bundle (%s) does not match the configured resource (%s).', $retrieved_bundle, $configured_bundle));
+      throw new NotFoundHttpException(sprintf('The loaded entity bundle (%s) does not match the configured resource (%s).', $retrieved_bundle, $configured_bundle));
     }
     return $defaults;
   }
