Skip to content

Commit 686a041

Browse files
committed
Allow \Throwable to be rendered
1 parent 8c25592 commit 686a041

File tree

11 files changed

+100
-45
lines changed

11 files changed

+100
-45
lines changed

src/Symfony/Component/Console/Application.php

+22-3
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ public function run(InputInterface $input = null, OutputInterface $output = null
132132
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : (class_exists(LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()));
133133
}
134134
if ($output instanceof ConsoleOutputInterface) {
135-
$this->renderException($e, $output->getErrorOutput());
135+
$this->renderThrowable($e, $output->getErrorOutput());
136136
} else {
137-
$this->renderException($e, $output);
137+
$this->renderThrowable($e, $output);
138138
}
139139
};
140140
if ($phpHandler = set_exception_handler($renderException)) {
@@ -768,20 +768,39 @@ public static function getAbbreviations($names)
768768

769769
/**
770770
* Renders a caught exception.
771+
*
772+
* @deprecated since Symfony 4.4, use "renderThrowable()" instead
771773
*/
772774
public function renderException(\Exception $e, OutputInterface $output)
775+
{
776+
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', \get_class($this)));
777+
778+
$this->renderThrowable($e, $output);
779+
}
780+
781+
public function renderThrowable(\Throwable $e, OutputInterface $output): void
773782
{
774783
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
775784

776-
$this->doRenderException($e, $output);
785+
$this->doRenderThrowable($e, $output);
777786

778787
if (null !== $this->runningCommand) {
779788
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
780789
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
781790
}
782791
}
783792

793+
/**
794+
* @deprecated since Symfony 4.4, use "doRenderThrowable()" instead
795+
*/
784796
protected function doRenderException(\Exception $e, OutputInterface $output)
797+
{
798+
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', \get_class($this)));
799+
800+
$this->doRenderThrowable($e, $output);
801+
}
802+
803+
protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void
785804
{
786805
do {
787806
$message = trim($e->getMessage());

src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php

+29-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpKernel\Event;
1313

14+
use Symfony\Component\ErrorHandler\Exception\FatalThrowableError;
1415
use Symfony\Component\HttpFoundation\Request;
1516
use Symfony\Component\HttpKernel\HttpKernelInterface;
1617

@@ -19,45 +20,62 @@
1920
*/
2021
class GetResponseForExceptionEvent extends RequestEvent
2122
{
22-
/**
23-
* The exception object.
24-
*
25-
* @var \Exception
26-
*/
27-
private $exception;
23+
private $throwable;
2824

2925
/**
3026
* @var bool
3127
*/
3228
private $allowCustomResponseCode = false;
3329

34-
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Exception $e)
30+
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e)
3531
{
3632
parent::__construct($kernel, $request, $requestType);
3733

38-
$this->setException($e);
34+
$this->throwable = $e;
3935
}
4036

4137
/**
42-
* Returns the thrown exception.
38+
* Returns the thrown exception / error.
39+
*
40+
* @deprecated since Symfony 4.4, use "getThrowable()" instead
4341
*
4442
* @return \Exception The thrown exception
4543
*/
4644
public function getException()
4745
{
48-
return $this->exception;
46+
@trigger_error(sprintf('The "%s::getException()" method is deprecated since Symfony 4.4, use "getThrowable()" instead.', \get_class($this)));
47+
48+
if (!$this->throwable instanceof \Exception) {
49+
return new FatalThrowableError($this->throwable);
50+
}
51+
52+
return $this->getThrowable();
53+
}
54+
55+
public function getThrowable(): \Throwable
56+
{
57+
return $this->throwable;
4958
}
5059

5160
/**
5261
* Replaces the thrown exception.
5362
*
5463
* This exception will be thrown if no response is set in the event.
5564
*
65+
* @deprecated since Symfony 4.4, use "setThrowable()" instead
66+
*
5667
* @param \Exception $exception The thrown exception
5768
*/
5869
public function setException(\Exception $exception)
5970
{
60-
$this->exception = $exception;
71+
@trigger_error(sprintf('The "%s::setException()" method is deprecated since Symfony 4.4, use "setThrowable()" instead.', \get_class($this)));
72+
73+
$this->setThrowable($exception);
74+
}
75+
76+
public function setThrowable(\Throwable $throwable): void
77+
{
78+
$this->throwable = $throwable;
6179
}
6280

6381
/**

src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public function configure(Event $event = null)
130130
$output = $output->getErrorOutput();
131131
}
132132
$this->exceptionHandler = function ($e) use ($app, $output) {
133-
$app->renderException($e, $output);
133+
$app->renderThrowable($e, $output);
134134
};
135135
}
136136
}

src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php

+18-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\HttpKernel\EventListener;
1313

1414
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\ErrorHandler\Exception\FatalThrowableError;
1516
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
1617
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1718
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -42,9 +43,9 @@ public function __construct($controller, LoggerInterface $logger = null, $debug
4243

4344
public function logKernelException(GetResponseForExceptionEvent $event)
4445
{
45-
$e = FlattenException::createFromThrowable($event->getException());
46+
$e = FlattenException::createFromThrowable($event->getThrowable());
4647

47-
$this->logException($event->getException(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
48+
$this->logThrowable($event->getThrowable(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
4849
}
4950

5051
public function onKernelException(GetResponseForExceptionEvent $event)
@@ -53,7 +54,11 @@ public function onKernelException(GetResponseForExceptionEvent $event)
5354
return;
5455
}
5556

56-
$exception = $event->getException();
57+
$exception = $event->getThrowable();
58+
if (!$exception instanceof \Exception) {
59+
$exception = new FatalThrowableError($exception);
60+
}
61+
5762
$request = $this->duplicateRequest($exception, $event->getRequest());
5863
$eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null;
5964

@@ -62,7 +67,7 @@ public function onKernelException(GetResponseForExceptionEvent $event)
6267
} catch (\Exception $e) {
6368
$f = FlattenException::createFromThrowable($e);
6469

65-
$this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), $e->getFile(), $e->getLine()));
70+
$this->logThrowable($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), $e->getFile(), $e->getLine()));
6671

6772
$prev = $e;
6873
do {
@@ -104,8 +109,17 @@ public static function getSubscribedEvents()
104109
*
105110
* @param \Exception $exception The \Exception instance
106111
* @param string $message The error message to log
112+
*
113+
* @deprecated since Symfony 4.4, use "logThrowable()" instead
107114
*/
108115
protected function logException(\Exception $exception, $message)
116+
{
117+
@trigger_error(sprintf('The "%s::logException()" method is deprecated since Symfony 4.4, use "logThrowable()" instead.', \get_class($this)));
118+
119+
$this->logThrowable($exception, $message);
120+
}
121+
122+
protected function logThrowable(\Throwable $exception, string $message): void
109123
{
110124
if (null !== $this->logger) {
111125
if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {

src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpKernel\EventListener;
1313

14+
use Symfony\Component\ErrorHandler\Exception\FatalThrowableError;
1415
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1516
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
1617
use Symfony\Component\HttpFoundation\RequestStack;
@@ -62,7 +63,10 @@ public function onKernelException(GetResponseForExceptionEvent $event)
6263
return;
6364
}
6465

65-
$this->exception = $event->getException();
66+
$this->exception = $event->getThrowable();
67+
if (!$this->exception instanceof \Exception) {
68+
$this->exception = new FatalThrowableError($this->exception);
69+
}
6670
}
6771

6872
/**

src/Symfony/Component/HttpKernel/EventListener/RouterListener.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function onKernelRequest(GetResponseEvent $event)
144144

145145
public function onKernelException(GetResponseForExceptionEvent $event)
146146
{
147-
if (!$this->debug || !($e = $event->getException()) instanceof NotFoundHttpException) {
147+
if (!$this->debug || !($e = $event->getThrowable()) instanceof NotFoundHttpException) {
148148
return;
149149
}
150150

src/Symfony/Component/HttpKernel/HttpKernel.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
7676
throw $e;
7777
}
7878

79-
return $this->handleException($e, $request, $type);
79+
return $this->handleThrowable($e, $request, $type);
8080
}
8181
}
8282

@@ -91,13 +91,13 @@ public function terminate(Request $request, Response $response)
9191
/**
9292
* @internal
9393
*/
94-
public function terminateWithException(\Exception $exception, Request $request = null)
94+
public function terminateWithException(\Throwable $exception, Request $request = null)
9595
{
9696
if (!$request = $request ?: $this->requestStack->getMasterRequest()) {
9797
throw $exception;
9898
}
9999

100-
$response = $this->handleException($exception, $request, self::MASTER_REQUEST);
100+
$response = $this->handleThrowable($exception, $request, self::MASTER_REQUEST);
101101

102102
$response->sendHeaders();
103103
$response->sendContent();
@@ -203,19 +203,19 @@ private function finishRequest(Request $request, int $type)
203203
}
204204

205205
/**
206-
* Handles an exception by trying to convert it to a Response.
206+
* Handles a throwable by trying to convert it to a Response.
207207
*
208208
* @param int $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
209209
*
210-
* @throws \Exception
210+
* @throws \Throwable
211211
*/
212-
private function handleException(\Exception $e, Request $request, int $type): Response
212+
private function handleThrowable(\Throwable $e, Request $request, int $type): Response
213213
{
214214
$event = new ExceptionEvent($this, $request, $type, $e);
215215
$this->dispatcher->dispatch($event, KernelEvents::EXCEPTION);
216216

217217
// a listener might have replaced the exception
218-
$e = $event->getException();
218+
$e = $event->getThrowable();
219219

220220
if (!$event->hasResponse()) {
221221
$this->finishRequest($request, $type);

src/Symfony/Component/HttpKernel/KernelEvents.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ final class KernelEvents
3030
const REQUEST = 'kernel.request';
3131

3232
/**
33-
* The EXCEPTION event occurs when an uncaught exception appears.
33+
* The EXCEPTION event occurs when an uncaught exception / error appears.
3434
*
35-
* This event allows you to create a response for a thrown exception or
36-
* to modify the thrown exception.
35+
* This event allows you to create a response for a thrown exception / error or
36+
* to modify the thrown exception / error.
3737
*
3838
* @Event("Symfony\Component\HttpKernel\Event\ExceptionEvent")
3939
*/

src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public function testConsoleEvent()
124124
$this->assertInstanceOf('Closure', $xHandler);
125125

126126
$app->expects($this->once())
127-
->method('renderException');
127+
->method('renderThrowable');
128128

129129
$xHandler(new \Exception());
130130
}

src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public function unregister(EventDispatcherInterface $dispatcher)
8989
*/
9090
public function onKernelException(GetResponseForExceptionEvent $event)
9191
{
92-
$exception = $event->getException();
92+
$exception = $event->getThrowable();
9393
do {
9494
if ($exception instanceof AuthenticationException) {
9595
return $this->handleAuthenticationException($event, $exception);
@@ -111,13 +111,13 @@ private function handleAuthenticationException(GetResponseForExceptionEvent $eve
111111
$event->setResponse($this->startAuthentication($event->getRequest(), $exception));
112112
$event->allowCustomResponseCode();
113113
} catch (\Exception $e) {
114-
$event->setException($e);
114+
$event->setThrowable($e);
115115
}
116116
}
117117

118118
private function handleAccessDeniedException(GetResponseForExceptionEvent $event, AccessDeniedException $exception)
119119
{
120-
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
120+
$event->setThrowable(new AccessDeniedHttpException($exception->getMessage(), $exception));
121121

122122
$token = $this->tokenStorage->getToken();
123123
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
@@ -131,7 +131,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
131131

132132
$event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
133133
} catch (\Exception $e) {
134-
$event->setException($e);
134+
$event->setThrowable($e);
135135
}
136136

137137
return;
@@ -160,7 +160,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
160160
$this->logger->error('An exception was thrown when handling an AccessDeniedException.', ['exception' => $e]);
161161
}
162162

163-
$event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
163+
$event->setThrowable(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
164164
}
165165
}
166166

0 commit comments

Comments
 (0)