3 namespace Drupal\serialization\EventSubscriber;
5 use Drupal\Core\Cache\CacheableDependencyInterface;
6 use Drupal\Core\Cache\CacheableResponse;
7 use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
8 use Symfony\Component\HttpFoundation\Response;
9 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
10 use Symfony\Component\Serializer\SerializerInterface;
13 * Handles default error responses in serialization formats.
15 class DefaultExceptionSubscriber extends HttpExceptionSubscriberBase {
20 * @var \Symfony\Component\Serializer\Serializer
22 protected $serializer;
25 * The available serialization formats.
29 protected $serializerFormats = [];
32 * DefaultExceptionSubscriber constructor.
34 * @param \Symfony\Component\Serializer\SerializerInterface $serializer
35 * The serializer service.
36 * @param array $serializer_formats
37 * The available serialization formats.
39 public function __construct(SerializerInterface $serializer, array $serializer_formats) {
40 $this->serializer = $serializer;
41 $this->serializerFormats = $serializer_formats;
47 protected function getHandledFormats() {
48 return $this->serializerFormats;
54 protected static function getPriority() {
55 // This will fire after the most common HTML handler, since HTML requests
56 // are still more common than HTTP requests. But it has a lower priority
57 // than \Drupal\Core\EventSubscriber\ExceptionJsonSubscriber::on4xx(), so
58 // that this also handles the 'json' format. Then all serialization formats
59 // (::getHandledFormats()) are handled by this exception subscriber, which
60 // results in better consistency.
65 * Handles all 4xx errors for all serialization failures.
67 * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
68 * The event to process.
70 public function on4xx(GetResponseForExceptionEvent $event) {
71 /** @var \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $exception */
72 $exception = $event->getException();
73 $request = $event->getRequest();
75 $format = $request->getRequestFormat();
76 $content = ['message' => $exception->getMessage()];
77 $encoded_content = $this->serializer->serialize($content, $format);
78 $headers = $exception->getHeaders();
80 // Add the MIME type from the request to send back in the header.
81 $headers['Content-Type'] = $request->getMimeType($format);
83 // If the exception is cacheable, generate a cacheable response.
84 if ($exception instanceof CacheableDependencyInterface) {
85 $response = new CacheableResponse($encoded_content, $exception->getStatusCode(), $headers);
86 $response->addCacheableDependency($exception);
89 $response = new Response($encoded_content, $exception->getStatusCode(), $headers);
92 $event->setResponse($response);