ensured that an exception is always converted to an error response (and that we keep the HTTP status code and headers)
This commit is contained in:
parent
46071f3238
commit
3f05e7047f
@ -45,7 +45,7 @@ class ExceptionController extends ContainerAware
|
||||
$templating = $this->container->get('templating');
|
||||
$code = $exception->getStatusCode();
|
||||
|
||||
$response = $templating->renderResponse(
|
||||
return $templating->renderResponse(
|
||||
$this->findTemplate($templating, $format, $code, $this->container->get('kernel')->isDebug()),
|
||||
array(
|
||||
'status_code' => $code,
|
||||
@ -55,11 +55,6 @@ class ExceptionController extends ContainerAware
|
||||
'currentContent' => $currentContent,
|
||||
)
|
||||
);
|
||||
|
||||
$response->setStatusCode($code);
|
||||
$response->headers->replace($exception->getHeaders());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,10 +35,6 @@ class ExceptionControllerTest extends TestCase
|
||||
->expects($this->once())
|
||||
->method('getStatusCode')
|
||||
->will($this->returnValue(404));
|
||||
$this->flatten
|
||||
->expects($this->once())
|
||||
->method('getHeaders')
|
||||
->will($this->returnValue(array()));
|
||||
$this->controller = new ExceptionController();
|
||||
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
||||
$this->templating = $this->getMockBuilder('Symfony\\Bundle\\TwigBundle\\TwigEngine')
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
@ -191,10 +192,23 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
|
||||
// ensure that we actually have an error response
|
||||
if (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
|
||||
if ($e instanceof HttpExceptionInterface) {
|
||||
// keep the HTTP status code and headers
|
||||
$response->setStatusCode($e->getStatusCode());
|
||||
$response->headers->add($e->getHeaders());
|
||||
} else {
|
||||
$response->setStatusCode(500);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->filterResponse($event->getResponse(), $request, $type);
|
||||
return $this->filterResponse($response, $request, $type);
|
||||
} catch (\Exception $e) {
|
||||
return $event->getResponse();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,11 @@ namespace Symfony\Component\HttpKernel\Tests;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
@ -59,8 +62,38 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException('foo'); }));
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
|
||||
$this->assertEquals('500', $response->getStatusCode());
|
||||
$this->assertEquals('foo', $response->getContent());
|
||||
}
|
||||
|
||||
public function testHandleExceptionWithARedirectionResponse()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
|
||||
$event->setResponse(new RedirectResponse('/login', 301));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new AccessDeniedHttpException(); }));
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals('301', $response->getStatusCode());
|
||||
$this->assertEquals('/login', $response->headers->get('Location'));
|
||||
}
|
||||
|
||||
public function testHandleHttpException()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
|
||||
$event->setResponse(new Response($event->getException()->getMessage()));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new MethodNotAllowedHttpException(array('POST')); }));
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals('405', $response->getStatusCode());
|
||||
$this->assertEquals('POST', $response->headers->get('Allow'));
|
||||
}
|
||||
|
||||
public function testHandleWhenAListenerReturnsAResponse()
|
||||
|
@ -129,7 +129,6 @@ class ExceptionListener
|
||||
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
|
||||
|
||||
$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
|
||||
$response->setStatusCode(403);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user