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');
|
$templating = $this->container->get('templating');
|
||||||
$code = $exception->getStatusCode();
|
$code = $exception->getStatusCode();
|
||||||
|
|
||||||
$response = $templating->renderResponse(
|
return $templating->renderResponse(
|
||||||
$this->findTemplate($templating, $format, $code, $this->container->get('kernel')->isDebug()),
|
$this->findTemplate($templating, $format, $code, $this->container->get('kernel')->isDebug()),
|
||||||
array(
|
array(
|
||||||
'status_code' => $code,
|
'status_code' => $code,
|
||||||
@ -55,11 +55,6 @@ class ExceptionController extends ContainerAware
|
|||||||
'currentContent' => $currentContent,
|
'currentContent' => $currentContent,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$response->setStatusCode($code);
|
|
||||||
$response->headers->replace($exception->getHeaders());
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,10 +35,6 @@ class ExceptionControllerTest extends TestCase
|
|||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getStatusCode')
|
->method('getStatusCode')
|
||||||
->will($this->returnValue(404));
|
->will($this->returnValue(404));
|
||||||
$this->flatten
|
|
||||||
->expects($this->once())
|
|
||||||
->method('getHeaders')
|
|
||||||
->will($this->returnValue(array()));
|
|
||||||
$this->controller = new ExceptionController();
|
$this->controller = new ExceptionController();
|
||||||
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
||||||
$this->templating = $this->getMockBuilder('Symfony\\Bundle\\TwigBundle\\TwigEngine')
|
$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\Controller\ControllerResolverInterface;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
@ -191,10 +192,23 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
|||||||
throw $e;
|
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 {
|
try {
|
||||||
return $this->filterResponse($event->getResponse(), $request, $type);
|
return $this->filterResponse($response, $request, $type);
|
||||||
} catch (\Exception $e) {
|
} 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\HttpKernel;
|
||||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
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\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
|
|
||||||
class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
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'); }));
|
$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()
|
public function testHandleWhenAListenerReturnsAResponse()
|
||||||
|
@ -129,7 +129,6 @@ class ExceptionListener
|
|||||||
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
|
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
|
||||||
|
|
||||||
$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
|
$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
|
||||||
$response->setStatusCode(403);
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user