Skip to content

[HttpKernel] make ExceptionEvent able to propagate any throwable #34309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADE-4.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ HttpKernel
* Marked the `RouterDataCollector::collect()` method as `@final`.
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
* Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
* Deprecated class `ExceptionListener`, use `ErrorListener` instead

Lock
----
Expand Down
2 changes: 2 additions & 0 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ HttpKernel
* Removed `TranslatorListener` in favor of `LocaleAwareListener`
* The `DebugHandlersListener` class has been made `final`
* Removed `SaveSessionListener` in favor of `AbstractSessionListener`
* Removed methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
* Removed class `ExceptionListener`, use `ErrorListener` instead
* Added new Bundle directory convention consistent with standard skeletons:

```
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\KernelInterface;
Expand Down Expand Up @@ -211,7 +211,7 @@ private function renderRegistrationErrors(InputInterface $input, OutputInterface
$this->doRenderThrowable($error, $output);
} else {
if (!$error instanceof \Exception) {
$error = new ErrorException($error);
$error = new FatalThrowableError($error);
}

$this->doRenderException($error, $output);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<argument type="service" id="error_renderer" />
</service>

<service id="exception_listener" class="Symfony\Component\HttpKernel\EventListener\ExceptionListener">
<service id="exception_listener" class="Symfony\Component\HttpKernel\EventListener\ErrorListener">
<tag name="kernel.event_subscriber" />
<tag name="monolog.logger" channel="request" />
<argument>%kernel.error_controller%</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouteCollectionBuilder;
Expand All @@ -30,9 +30,9 @@ class ConcreteMicroKernel extends Kernel implements EventSubscriberInterface

private $cacheDir;

public function onKernelException(RequestEvent $event)
public function onKernelException(ExceptionEvent $event)
{
if ($event->getException() instanceof Danger) {
if ($event->getThrowable() instanceof Danger) {
$event->setResponse(Response::create('It\'s dangerous to go alone. Take this ⚔'));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function previewErrorPageAction(Request $request, $code)

/*
* This Request mimics the parameters set by
* \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with
* \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with
* the additional "showException" flag.
*/

Expand Down
7 changes: 3 additions & 4 deletions src/Symfony/Component/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Debug\ErrorHandler as LegacyErrorHandler;
use Symfony\Component\Debug\Exception\FatalThrowableError as LegacyFatalThrowableError;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\ErrorHandler\ErrorHandler;
use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Contracts\Service\ResetInterface;
Expand Down Expand Up @@ -809,7 +808,7 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);

if (!$e instanceof \Exception) {
$e = class_exists(ErrorException::class) ? new ErrorException($e) : (class_exists(LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()));
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
}

$this->renderException($e, $output);
Expand Down Expand Up @@ -848,7 +847,7 @@ protected function doRenderThrowable(\Throwable $e, OutputInterface $output): vo
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);

if (!$e instanceof \Exception) {
$e = class_exists(ErrorException::class) ? new ErrorException($e) : (class_exists(LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()));
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
}

$this->doRenderException($e, $output);
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Debug/Exception/FatalErrorException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@

namespace Symfony\Component\Debug\Exception;

@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Exception\ErrorException::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Error\FatalError::class), E_USER_DEPRECATED);

/**
* Fatal Error Exception.
*
* @author Konstanton Myakshin <koc-dp@yandex.ru>
*
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Error\FatalError instead.
*/
class FatalErrorException extends \ErrorException
{
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Debug/Exception/FatalThrowableError.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@

namespace Symfony\Component\Debug\Exception;

@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalThrowableError::class, \Symfony\Component\ErrorHandler\Exception\ErrorException::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', FatalThrowableError::class), E_USER_DEPRECATED);

/**
* Fatal Throwable Error.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
* @deprecated since Symfony 4.4
*/
class FatalThrowableError extends FatalErrorException
{
Expand Down
42 changes: 0 additions & 42 deletions src/Symfony/Component/ErrorHandler/Exception/ErrorException.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
namespace Symfony\Component\ErrorRenderer\Exception;

use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
Expand Down Expand Up @@ -70,7 +69,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromThrowable($exception);
$e->setClass($exception instanceof ErrorException ? $exception->getOriginalClassName() : \get_class($exception));
$e->setClass(\get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
namespace Symfony\Component\ErrorRenderer\Tests\Exception;

use PHPUnit\Framework\TestCase;
use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Expand Down Expand Up @@ -130,16 +129,6 @@ public function testFlattenHttpException(\Throwable $exception)
$this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');
}

public function testWrappedThrowable()
{
$exception = new ErrorException(new \DivisionByZeroError('Ouch', 42));
$flattened = FlattenException::createFromThrowable($exception);

$this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');
$this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');
$this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');
}

public function testThrowable()
{
$error = new \DivisionByZeroError('Ouch', 42);
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/HttpKernel/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ CHANGELOG
* Marked the `RouterDataCollector::collect()` method as `@final`.
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
* Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
* Deprecated class `ExceptionListener`, use `ErrorListener` instead

4.3.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function preview(Request $request, int $code): Response

/*
* This Request mimics the parameters set by
* \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with
* \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with
* the additional "showException" flag.
*/
$subRequest = $request->duplicate(null, null, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,55 @@
*/
class GetResponseForExceptionEvent extends RequestEvent
{
/**
* The exception object.
*
* @var \Exception
*/
private $throwable;
private $exception;

/**
* @var bool
*/
private $allowCustomResponseCode = false;

public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Exception $e)
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e)
{
parent::__construct($kernel, $request, $requestType);

$this->setException($e);
$this->setThrowable($e);
}

public function getThrowable(): \Throwable
{
return $this->throwable;
}

/**
* Replaces the thrown exception.
*
* This exception will be thrown if no response is set in the event.
*/
public function setThrowable(\Throwable $exception): void
{
$this->exception = null;
$this->throwable = $exception;
}

/**
* Returns the thrown exception.
* @deprecated since Symfony 4.4, use getThrowable instead
*
* @return \Exception The thrown exception
*/
public function getException()
{
return $this->exception;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "getThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);

return $this->exception ?? $this->exception = $this->throwable instanceof \Exception ? $this->throwable : new FatalThrowableError($this->throwable);
}

/**
* Replaces the thrown exception.
*
* This exception will be thrown if no response is set in the event.
* @deprecated since Symfony 4.4, use setThrowable instead
*
* @param \Exception $exception The thrown exception
*/
public function setException(\Exception $exception)
{
$this->exception = $exception;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "setThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);

$this->throwable = $this->exception = $exception;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\ErrorHandler\ErrorHandler;
use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
Expand Down Expand Up @@ -112,10 +112,6 @@ public function configure(Event $event = null)
throw $e;
}

if (!$e instanceof \Exception) {
$e = new ErrorException($e);
}

$hasRun = true;
$kernel->terminateWithException($e, $request);
};
Expand All @@ -130,7 +126,7 @@ public function configure(Event $event = null)
$app->renderThrowable($e, $output);
} else {
if (!$e instanceof \Exception) {
$e = new ErrorException($e);
$e = new FatalThrowableError($e);
}

$app->renderException($e, $output);
Expand Down
Loading