DefaultExceptionHtmlSubscriber::makeSubrequest

protected DefaultExceptionHtmlSubscriber::makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code)

Makes a subrequest to retrieve the default error page.

Parameters

\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event: The event to process.

string $url: The path/url to which to make a subrequest for this error message.

int $status_code: The status code for the error being handled.

File

core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php, line 122

Class

DefaultExceptionHtmlSubscriber
Exception subscriber for handling core default HTML error pages.

Namespace

Drupal\Core\EventSubscriber

Code

protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) {
  $request = $event->getRequest();
  $exception = $event->getException();

  try {
    // Reuse the exact same request (so keep the same URL, keep the access
    // result, the exception, et cetera) but override the routing information.
    // This means that aside from routing, this is identical to the master
    // request. This allows us to generate a response that is executed on
    // behalf of the master request, i.e. for the original URL. This is what
    // allows us to e.g. generate a 404 response for the original URL; if we
    // would execute a subrequest with the 404 route's URL, then it'd be
    // generated for *that* URL, not the *original* URL.
    $sub_request = clone $request;

    // The routing to the 404 page should be done as GET request because it is
    // restricted to GET and POST requests only. Otherwise a DELETE request
    // would for example trigger a method not allowed exception.
    $request_context = clone($this->accessUnawareRouter->getContext());
    $request_context->setMethod('GET');
    $this->accessUnawareRouter->setContext($request_context);

    $sub_request->attributes->add($this->accessUnawareRouter->match($url));

    // Add to query (GET) or request (POST) parameters:
    // - 'destination' (to ensure e.g. the login form in a 403 response
    //   redirects to the original URL)
    // - '_exception_statuscode'
    $parameters = $sub_request->isMethod('GET') ? $sub_request->query : $sub_request->request;
    $parameters->add($this->redirectDestination->getAsArray() + ['_exception_statuscode' => $status_code]);

    $response = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST);
    // Only 2xx responses should have their status code overridden; any
    // other status code should be passed on: redirects (3xx), error (5xx)…
    // @see https://www.drupal.org/node/2603788#comment-10504916
    if ($response->isSuccessful()) {
      $response->setStatusCode($status_code);
    }

    // Persist any special HTTP headers that were set on the exception.
    if ($exception instanceof HttpExceptionInterface) {
      $response->headers->add($exception->getHeaders());
    }

    $event->setResponse($response);
  }
  catch (\Exception $e) {
    // If an error happened in the subrequest we can't do much else. Instead,
    // just log it. The DefaultExceptionSubscriber will catch the original
    // exception and handle it normally.
    $error = Error::decodeException($e);
    $this->logger->log($error['severity_level'], '%type: @message in %function (line %line of %file).', $error);
  }
}
doc_Drupal
2016-10-29 09:01:36
Comments
Leave a Comment

Please login to continue.