Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 538a38c

Browse files
committed
ensured that an exception is always converted to an error response (and that we keep the HTTP status code and headers)
1 parent bccac39 commit 538a38c

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

HttpKernel.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
1515
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16+
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
1617
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
1718
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
1819
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -191,10 +192,23 @@ private function handleException(\Exception $e, $request, $type)
191192
throw $e;
192193
}
193194

195+
$response = $event->getResponse();
196+
197+
// ensure that we actually have an error response
198+
if (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
199+
if ($e instanceof HttpExceptionInterface) {
200+
// keep the HTTP status code and headers
201+
$response->setStatusCode($e->getStatusCode());
202+
$response->headers->add($e->getHeaders());
203+
} else {
204+
$response->setStatusCode(500);
205+
}
206+
}
207+
194208
try {
195-
return $this->filterResponse($event->getResponse(), $request, $type);
209+
return $this->filterResponse($response, $request, $type);
196210
} catch (\Exception $e) {
197-
return $event->getResponse();
211+
return $response;
198212
}
199213
}
200214

Tests/HttpKernelTest.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
use Symfony\Component\HttpKernel\HttpKernel;
1515
use Symfony\Component\HttpKernel\HttpKernelInterface;
1616
use Symfony\Component\HttpKernel\KernelEvents;
17+
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
18+
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
1719
use Symfony\Component\HttpFoundation\Request;
1820
use Symfony\Component\HttpFoundation\Response;
21+
use Symfony\Component\HttpFoundation\RedirectResponse;
1922
use Symfony\Component\EventDispatcher\EventDispatcher;
2023

2124
class HttpKernelTest extends \PHPUnit_Framework_TestCase
@@ -59,8 +62,38 @@ public function testHandleWhenControllerThrowsAnExceptionAndRawIsFalse()
5962
});
6063

6164
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException('foo'); }));
65+
$response = $kernel->handle(new Request());
6266

63-
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
67+
$this->assertEquals('500', $response->getStatusCode());
68+
$this->assertEquals('foo', $response->getContent());
69+
}
70+
71+
public function testHandleExceptionWithARedirectionResponse()
72+
{
73+
$dispatcher = new EventDispatcher();
74+
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
75+
$event->setResponse(new RedirectResponse('/login', 301));
76+
});
77+
78+
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new AccessDeniedHttpException(); }));
79+
$response = $kernel->handle(new Request());
80+
81+
$this->assertEquals('301', $response->getStatusCode());
82+
$this->assertEquals('/login', $response->headers->get('Location'));
83+
}
84+
85+
public function testHandleHttpException()
86+
{
87+
$dispatcher = new EventDispatcher();
88+
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
89+
$event->setResponse(new Response($event->getException()->getMessage()));
90+
});
91+
92+
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new MethodNotAllowedHttpException(array('POST')); }));
93+
$response = $kernel->handle(new Request());
94+
95+
$this->assertEquals('405', $response->getStatusCode());
96+
$this->assertEquals('POST', $response->headers->get('Allow'));
6497
}
6598

6699
public function testHandleWhenAListenerReturnsAResponse()

0 commit comments

Comments
 (0)