Sometimes, when handling exceptions in your Symfony applications, you may want
to change the original HTTP response status code (for example to return a 404
error instead of the original 5xx
code).
Of course you should not do this without a good reason, but Symfony lets you do
it by setting a special X-Status-Code
HTTP header:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
// 500 is the original status code; but the end user will get a 404
$response = new Response('...', 500, ['X-Status-Code' => 404]);
// ...
$event->setResponse($response);
}
The X-Status-Code
header is not a standard HTTP feature, so it has always
bugged us. In Symfony 3.3, we finally decided to get rid of it and stick to the
standard way of dealing with HTTP responses.
Instead of the X-Status-Code
header, now you can set the status code as
usual in the response and then, call the new allowCustomResponseCode()
method to tell the Kernel to use the response code set on the event's response
object:
1 2 3 4 5 6 7 8 9 10
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$response = new Response('...', 404);
// ...
$event->allowCustomResponseCode();
$event->setResponse($response);
}
I don't get why X-Status-Code was used before, actually :/
From the top of my head I can imagine a scenario similar to GitHub, where when you try to access a private repository you don't have access to you get a 404 instead of the actual 401/403. So I guess you could use it for preventing information leakage. I'd probably try a ResponseListener first instead, so probably still a bit of a contrived example.
Another use case is to avoid returning 5xx status code when an error happens (and return instead a 200 status) so Google's crawler doesn't penalize the web site if there is a sudden rise in the application errors.
Is "allowCustomResponseCode()" actually necessary? Or what response code would Symfony return if that method is not called - something other than the 404 code of the Response object?
I just always assumed Symfony would use the response code of the Response object.
Yes, calling to allowCustomResponseCode() in this particular case is needed (of course is not needed to set the response status code in normal circumstances). However, in https://github.com/symfony/symfony/issues/22019 you can read more about this feature and Fabien says that nobody should really use this feature in their apps.