diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml index 7220c73f17..2204ba7b0f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml @@ -22,7 +22,7 @@ %kernel.debug% %kernel.charset% - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/error_catcher.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/error_catcher.xml index 574b2280f6..d2810aff2b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/error_catcher.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/error_catcher.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd"> - + diff --git a/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorCatcherPass.php b/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorCatcherPass.php index dd3830f2d3..a6c17c9f8f 100644 --- a/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorCatcherPass.php +++ b/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorCatcherPass.php @@ -25,7 +25,7 @@ class ErrorCatcherPass implements CompilerPassInterface private $rendererService; private $rendererTag; - public function __construct(string $rendererService = 'error_catcher.error_renderer', string $rendererTag = 'error_catcher.renderer') + public function __construct(string $rendererService = 'error_catcher.error_formatter', string $rendererTag = 'error_catcher.renderer') { $this->rendererService = $rendererService; $this->rendererTag = $rendererTag; diff --git a/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorRenderer.php b/src/Symfony/Component/ErrorCatcher/DependencyInjection/LazyLoadingErrorFormatter.php similarity index 88% rename from src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorRenderer.php rename to src/Symfony/Component/ErrorCatcher/DependencyInjection/LazyLoadingErrorFormatter.php index ea7d331025..451814257e 100644 --- a/src/Symfony/Component/ErrorCatcher/DependencyInjection/ErrorRenderer.php +++ b/src/Symfony/Component/ErrorCatcher/DependencyInjection/LazyLoadingErrorFormatter.php @@ -12,14 +12,14 @@ namespace Symfony\Component\ErrorCatcher\DependencyInjection; use Psr\Container\ContainerInterface; -use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRenderer as BaseErrorRenderer; +use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorFormatter; /** * Lazily loads error renderers from the dependency injection container. * * @author Yonel Ceruto */ -class ErrorRenderer extends BaseErrorRenderer +class LazyLoadingErrorFormatter extends ErrorFormatter { private $container; private $initialized = []; diff --git a/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRenderer.php b/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorFormatter.php similarity index 71% rename from src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRenderer.php rename to src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorFormatter.php index bf2a1b1d51..2dd10fe4fe 100644 --- a/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRenderer.php +++ b/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorFormatter.php @@ -15,33 +15,38 @@ use Symfony\Component\ErrorCatcher\Exception\ErrorRendererNotFoundException; use Symfony\Component\ErrorCatcher\Exception\FlattenException; /** - * Renders an Exception that represents a Response content. + * Formats an exception to be used as response content. + * + * It delegates to implementations of ErrorRendererInterface depending on the format. * * @see ErrorRendererInterface * * @author Yonel Ceruto */ -class ErrorRenderer +class ErrorFormatter { private $renderers = []; /** * @param ErrorRendererInterface[] $renderers */ - public function __construct(array $renderers) + public function __construct(iterable $renderers) { foreach ($renderers as $renderer) { - if (!$renderer instanceof ErrorRendererInterface) { - throw new \InvalidArgumentException(sprintf('Error renderer "%s" must implement "%s".', \get_class($renderer), ErrorRendererInterface::class)); - } - - $this->addRenderer($renderer, $renderer::getFormat()); + $this->addRenderer($renderer); } } - public function addRenderer(ErrorRendererInterface $renderer, string $format): self + /** + * Registers an error renderer that is format specific. + * + * By passing an explicit format you can register a renderer for a different format than what + * ErrorRendererInterface::getFormat() would return in order to register the same renderer for + * several format aliases. + */ + public function addRenderer(ErrorRendererInterface $renderer, string $format = null): self { - $this->renderers[$format] = $renderer; + $this->renderers[$format ?? $renderer::getFormat()] = $renderer; return $this; } diff --git a/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRendererInterface.php b/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRendererInterface.php index 61c1f61f38..ea9fde40aa 100644 --- a/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRendererInterface.php +++ b/src/Symfony/Component/ErrorCatcher/ErrorRenderer/ErrorRendererInterface.php @@ -14,23 +14,19 @@ namespace Symfony\Component\ErrorCatcher\ErrorRenderer; use Symfony\Component\ErrorCatcher\Exception\FlattenException; /** - * Interface implemented by all error renderers. + * Interface for classes that can render errors in a specific format. * * @author Yonel Ceruto */ interface ErrorRendererInterface { /** - * Gets the format of the content. - * - * @return string The content format + * Gets the format this renderer can return errors as. */ public static function getFormat(): string; /** - * Renders an Exception and returns the Response content. - * - * @return string The Response content as a string + * Returns the response content of the rendered exception. */ public function render(FlattenException $exception): string; } diff --git a/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorCatcherPassTest.php b/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorCatcherPassTest.php index ed2162b661..f111ef4687 100644 --- a/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorCatcherPassTest.php +++ b/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorCatcherPassTest.php @@ -17,17 +17,17 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\ErrorCatcher\DependencyInjection\ErrorCatcherPass; -use Symfony\Component\ErrorCatcher\DependencyInjection\ErrorRenderer; +use Symfony\Component\ErrorCatcher\DependencyInjection\LazyLoadingErrorFormatter; use Symfony\Component\ErrorCatcher\ErrorRenderer\HtmlErrorRenderer; use Symfony\Component\ErrorCatcher\ErrorRenderer\JsonErrorRenderer; -class ErrorPassTest extends TestCase +class ErrorCatcherPassTest extends TestCase { public function testProcess() { $container = new ContainerBuilder(); $container->setParameter('kernel.debug', true); - $definition = $container->register('error_catcher.error_renderer', ErrorRenderer::class) + $definition = $container->register('error_catcher.error_formatter', LazyLoadingErrorFormatter::class) ->addArgument([]) ; $container->register('error_catcher.renderer.html', HtmlErrorRenderer::class) diff --git a/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorRendererTest.php b/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/LazyLoadingErrorFormatterTest.php similarity index 77% rename from src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorRendererTest.php rename to src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/LazyLoadingErrorFormatterTest.php index 4fb7799d75..b9be715eb7 100644 --- a/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/ErrorRendererTest.php +++ b/src/Symfony/Component/ErrorCatcher/Tests/DependencyInjection/LazyLoadingErrorFormatterTest.php @@ -12,11 +12,12 @@ namespace Symfony\Component\ErrorCatcher\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Component\ErrorCatcher\DependencyInjection\ErrorRenderer; +use Psr\Container\ContainerInterface; +use Symfony\Component\ErrorCatcher\DependencyInjection\LazyLoadingErrorFormatter; use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRendererInterface; use Symfony\Component\ErrorCatcher\Exception\FlattenException; -class ErrorRendererTest extends TestCase +class LazyLoadingErrorFormatterTest extends TestCase { /** * @expectedException \Symfony\Component\ErrorCatcher\Exception\ErrorRendererNotFoundException @@ -24,16 +25,16 @@ class ErrorRendererTest extends TestCase */ public function testInvalidErrorRenderer() { - $container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock(); + $container = $this->getMockBuilder(ContainerInterface::class)->getMock(); $container->expects($this->once())->method('has')->with('foo')->willReturn(false); $exception = FlattenException::createFromThrowable(new \Exception('Foo')); - (new ErrorRenderer($container))->render($exception, 'foo'); + (new LazyLoadingErrorFormatter($container))->render($exception, 'foo'); } public function testCustomErrorRenderer() { - $container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock(); + $container = $this->getMockBuilder(ContainerInterface::class)->getMock(); $container ->expects($this->once()) ->method('has') @@ -46,7 +47,7 @@ class ErrorRendererTest extends TestCase ->willReturn(new FooErrorRenderer()) ; - $errorRenderer = new ErrorRenderer($container); + $errorRenderer = new LazyLoadingErrorFormatter($container); $exception = FlattenException::createFromThrowable(new \RuntimeException('Foo')); $this->assertSame('Foo', $errorRenderer->render($exception, 'foo')); diff --git a/src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorRendererTest.php b/src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorFormatterTest.php similarity index 71% rename from src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorRendererTest.php rename to src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorFormatterTest.php index e839ceb1e2..a2596fe28f 100644 --- a/src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorRendererTest.php +++ b/src/Symfony/Component/ErrorCatcher/Tests/ErrorRenderer/ErrorFormatterTest.php @@ -12,11 +12,11 @@ namespace Symfony\Component\ErrorCatcher\Tests\ErrorRenderer; use PHPUnit\Framework\TestCase; -use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRenderer; +use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorFormatter; use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRendererInterface; use Symfony\Component\ErrorCatcher\Exception\FlattenException; -class ErrorRendererTest extends TestCase +class ErrorFormatterTest extends TestCase { /** * @expectedException \Symfony\Component\ErrorCatcher\Exception\ErrorRendererNotFoundException @@ -25,23 +25,21 @@ class ErrorRendererTest extends TestCase public function testErrorRendererNotFound() { $exception = FlattenException::createFromThrowable(new \Exception('foo')); - (new ErrorRenderer([]))->render($exception, 'foo'); + (new ErrorFormatter([]))->render($exception, 'foo'); } /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Error renderer "stdClass" must implement "Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRendererInterface". + * @expectedException \TypeError */ public function testInvalidErrorRenderer() { - $exception = FlattenException::createFromThrowable(new \Exception('foo')); - (new ErrorRenderer([new \stdClass()]))->render($exception, 'foo'); + new ErrorFormatter([new \stdClass()]); } public function testCustomErrorRenderer() { $renderers = [new FooErrorRenderer()]; - $errorRenderer = new ErrorRenderer($renderers); + $errorRenderer = new ErrorFormatter($renderers); $exception = FlattenException::createFromThrowable(new \RuntimeException('Foo')); $this->assertSame('Foo', $errorRenderer->render($exception, 'foo')); diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php index 4ab92f8975..b0b9a94c28 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php @@ -16,7 +16,7 @@ use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\ErrorCatcher\ErrorHandler; -use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRenderer; +use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorFormatter; use Symfony\Component\ErrorCatcher\ErrorRenderer\HtmlErrorRenderer; use Symfony\Component\ErrorCatcher\Exception\ErrorRendererNotFoundException; use Symfony\Component\ErrorCatcher\ExceptionHandler; @@ -46,7 +46,7 @@ class DebugHandlersListener implements EventSubscriberInterface private $fileLinkFormat; private $scope; private $charset; - private $errorRenderer; + private $errorFormatter; private $firstCall = true; private $hasTerminatedWithException; @@ -59,7 +59,7 @@ class DebugHandlersListener implements EventSubscriberInterface * @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files * @param bool $scope Enables/disables scoping mode */ - public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, string $charset = null, ErrorRenderer $errorRenderer = null) + public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, string $charset = null, ErrorFormatter $errorFormatter = null) { $this->exceptionHandler = $exceptionHandler; $this->logger = $logger; @@ -69,7 +69,7 @@ class DebugHandlersListener implements EventSubscriberInterface $this->fileLinkFormat = $fileLinkFormat; $this->scope = $scope; $this->charset = $charset; - $this->errorRenderer = $errorRenderer; + $this->errorFormatter = $errorFormatter; } /** @@ -167,16 +167,16 @@ class DebugHandlersListener implements EventSubscriberInterface $debug = $this->scream && $this->scope; $controller = function (Request $request) use ($debug) { - if (null === $this->errorRenderer) { - $this->errorRenderer = new ErrorRenderer([new HtmlErrorRenderer($debug, $this->charset, $this->fileLinkFormat)]); + if (null === $this->errorFormatter) { + $this->errorFormatter = new ErrorFormatter([new HtmlErrorRenderer($debug, $this->charset, $this->fileLinkFormat)]); } $e = $request->attributes->get('exception'); try { - return new Response($this->errorRenderer->render($e, $request->getRequestFormat()), $e->getStatusCode(), $e->getHeaders()); + return new Response($this->errorFormatter->render($e, $request->getRequestFormat()), $e->getStatusCode(), $e->getHeaders()); } catch (ErrorRendererNotFoundException $_) { - return new Response($this->errorRenderer->render($e), $e->getStatusCode(), $e->getHeaders()); + return new Response($this->errorFormatter->render($e), $e->getStatusCode(), $e->getHeaders()); } };