8000 feature #33271 Added new ErrorController + Preview and enabling there… · symfony/symfony@b7371ea · GitHub
[go: up one dir, main page]

Skip to content

Commit b7371ea

Browse files
committed
feature #33271 Added new ErrorController + Preview and enabling there the error renderer mechanism (yceruto)
This PR was merged into the 4.4 branch. Discussion ---------- Added new ErrorController + Preview and enabling there the error renderer mechanism | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes (deps=high failure is normal) | Fixed tickets | - | License | MIT | Doc PR | TODO After deprecating the `ExceptionController` in TwigBundle (refs #31398) the `twig.exception_controller` config key becomes useless as feature provided by TwigBundle, while the preview controller is taking more relevance for the error renderer mechanish. **Proposal** * Deprecate the `twig.exception_controller` config key in favor of `framework.error_controller` with default `ErrorController` that activates the error renderer mechanism through the current `ExceptionListener`, meaning also that `DebugHandlersListener::onKernelException` method becomes useless too. * Deprecate the `PreviewErrorController` from TwigBundle in favor of similar in FrameworkBundle. So you no longer need to install TwigBundle to create a custom error controller or check the preview output of an error renderer (included `TwigHtmlErrorRenderer`). Btw this would fix #31398 (comment), removing here workaround in SecurityBundle. TODO: - [x] Update CHANGELOG & UPGRADE files - [x] Add tests WDYT? Commits ------- b79532a Add ErrorController to preview and render errors
2 parents 7a9c5da + b79532a commit b7371ea

File tree

38 files changed

+308
-130
lines changed

38 files changed

+308
-130
lines changed

UPGRADE-4.4.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,25 @@ TwigBridge
217217
TwigBundle
218218
----------
219219

220-
* Deprecated default value `twig.controller.exception::showAction` of the `twig.exception_controller` configuration option,
221-
set it to `null` instead. This will also change the default error response format according to https://tools.ietf.org/html/rfc7807
222-
for `json`, `xml`, `atom` and `txt` formats:
220+
* Deprecated `twig.exception_controller` configuration option, set it to "null" and use `framework.error_controller` instead:
221+
222+
Before:
223+
```yaml
224+
twig:
225+
exception_controller: 'App\Controller\MyExceptionController'
226+
```
227+
228+
After:
229+
```yaml
230+
twig:
231+
exception_controller: null
232+
233+
framework:
234+
error_controller: 'App\Controller\MyExceptionController'
235+
```
236+
237+
The new default exception controller will also change the error response content according to
238+
https://tools.ietf.org/html/rfc7807 for `json`, `xml`, `atom` and `txt` formats:
223239

224240
Before:
225241
```json
@@ -240,7 +256,8 @@ TwigBundle
240256
}
241257
```
242258

243-
* Deprecated the `ExceptionController` and all built-in error templates, use the error renderer mechanism of the `ErrorRenderer` component
259+
* Deprecated the `ExceptionController` and `PreviewErrorController` controllers, use `ErrorController` from the HttpKernel component instead
260+
* Deprecated all built-in error templates, use the error renderer mechanism of the `ErrorRenderer` component
244261
* Deprecated loading custom error templates in non-html formats. Custom HTML error pages based on Twig keep working as before:
245262

246263
Before (`templates/bundles/TwigBundle/Exception/error.jsonld.twig`):

UPGRADE-5.0.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ TwigBundle
538538
* The default value (`false`) of the `twig.strict_variables` configuration option has been changed to `%kernel.debug%`.
539539
* The `transchoice` tag and filter have been removed, use the `trans` ones instead with a `%count%` parameter.
540540
* Removed support for legacy templates directories `src/Resources/views/` and `src/Resources/<BundleName>/views/`, use `templates/` and `templates/bundles/<BundleName>/` instead.
541-
* The default value (`twig.controller.exception::showAction`) of the `twig.exception_controller` configuration option has been changed to `null`.
542-
* Removed `ExceptionController` class and all built-in error templates
541+
* The `twig.exception_controller` configuration option has been removed, use `framework.error_controller` instead.
542+
* Removed `ExceptionController`, `PreviewErrorController` classes and all built-in error templates
543543

544544
TwigBridge
545545
----------

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ CHANGELOG
1414
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
1515
* Not tagging service route loaders with `routing.route_loader` has been deprecated.
1616
* Overriding the methods `KernelTestCase::tearDown()` and `WebTestCase::tearDown()` without the `void` return-type is deprecated.
17-
17+
* Added new `error_controller` configuration to handle system exceptions
18+
1819
4.3.0
1920
-----
2021

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Symfony\Component\Mailer\Mailer;
2929
use Symfony\Component\Messenger\MessageBusInterface;
3030
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
31-
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
3231
use Symfony\Component\Serializer\Serializer;
3332
use Symfony\Component\Translation\Translator;
3433
use Symfony\Component\Validator\Validation;
@@ -84,6 +83,9 @@ public function getConfigTreeBuilder()
8483
->beforeNormalization()->ifString()->then(function ($v) { return [$v]; })->end()
8584
->prototype('scalar')->end()
8685
->end()
86+
->scalarNode('error_controller')
87+
->defaultValue('error_controller')
88+
->end()
8789
->end()
8890
;
8991

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ public function load(array $configs, ContainerBuilder $container)
212212
$container->setParameter('kernel.http_method_override', $config['http_method_override']);
213213
$container->setParameter('kernel.trusted_hosts', $config['trusted_hosts']);
214214
$container->setParameter('kernel.default_locale', $config['default_locale']);
215+
$container->setParameter('kernel.error_controller', $config['error_controller']);
215216

216217
if (!$container->hasParameter('debug.file_link_format')) {
217218
if (!$container->hasParameter('templating.helper.code.file_link_format')) {

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
<argument>%kernel.debug%</argument>
2222
<argument type="service" id="debug.file_link_formatter" />
2323
<argument>%kernel.debug%</argument>
24-
<argument>%kernel.charset%</argument>
25-
<argument type="service" id="error_renderer" on-invalid="null" />
2624
</service>
2725

2826
<service id="debug.file_link_formatter" class="Symfony\Component\HttpKernel\Debug\FileLinkFormatter">
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<routes xmlns="http://symfony.com/schema/routing"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/routing https://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<route id="_preview_error" path="/{code}.{_format}">
8+
<default key="_controller">error_controller::preview</default>
9+
<default key="_format">html</default>
10+
<requirement key="code">\d+</requirement>
11+
</route>
12+
</routes>

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<xsd:attribute name="secret" type="xsd:string" />
4242
<xsd:attribute name="default-locale" type="xsd:string" />
4343
<xsd:attribute name="test" type="xsd:boolean" />
44+
<xsd:attribute name="error-controller" type="xsd:string" />
4445
</xsd:complexType>
4546

4647
<xsd:complexType name="form">

src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,19 @@
8888
<service id="disallow_search_engine_index_response_listener" class="Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener">
8989
<tag name="kernel.event_subscriber" />
9090
</service>
91+
92+
<service id="error_controller" class="Symfony\Component\HttpKernel\Controller\ErrorController" public="true">
93+
<argument type="service" id="http_kernel" />
94+
<argument>%kernel.error_controller%</argument>
95+
<argument type="service" id="error_renderer" />
96+
</service>
97+
98+
<service id="exception_listener" class="Symfony\Component\HttpKernel\EventListener\ExceptionListener">
99+
<tag name="kernel.event_subscriber" />
100+
<tag name="monolog.logger" channel="request" />
101+
<argument>%kernel.error_controller%</argument>
102+
<argument type="service" id="logger" on-invalid="null" />
103+
<argument>%kernel.debug%</argument>
104+
</service>
91105
</services>
92106
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/Fixture/TestAppKernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function registerContainerConfiguration(LoaderInterface $loader)
3838

3939
public function setAnnotatedClassCache(array $annotatedClasses)
4040
{
41-
$annotatedClasses = array_diff($annotatedClasses, ['Symfony\Bundle\WebProfilerBundle\Controller\ExceptionController', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController']);
41+
$annotatedClasses = array_diff($annotatedClasses, ['Symfony\Bundle\WebProfilerBundle\Controller\ExceptionController', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController', 'Symfony\Bundle\TwigBundle\Controller\PreviewErrorController']);
4242

4343
parent::setAnnotatedClassCache($annotatedClasses);
4444
}

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
373373
'transports' => [],
374374
'enabled' => !class_exists(FullStack::class) && class_exists(Mailer::class),
375375
],
376+
'error_controller' => 'error_controller',
376377
];
377378
}
378379
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/BundlePaths/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ framework:
88

99
twig:
1010
strict_variables: '%kernel.debug%'
11-
exception_controller: ~
11+
exception_controller: null # to be removed in 5.0

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Fragment/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ framework:
77

88
twig:
99
strict_variables: '%kernel.debug%'
10-
exception_controller: ~
10+
exception_controller: null # to be removed in 5.0

src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ class MissingUserProviderTest extends AbstractWebTestCase
1515
{
1616
public function testUserProviderIsNeeded()
1717
{
18-
$this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException');
19-
$this->expectExceptionMessage('"default" firewall requires a user provider but none was defined.');
20-
$client = $this->createClient(['test_case' => 'MissingUserProvider', 'root_config' => 'config.yml']);
18+
$client = $this->createClient(['test_case' => 'MissingUserProvider', 'root_config' => 'config.yml', 'debug' => true]);
2119

2220
$client->request('GET', '/', [], [], [
2321
'PHP_AUTH_USER' => 'username',
2422
'PHP_AUTH_PW' => 'pa$$word',
2523
]);
24+
25+
$response = $client->getResponse();
26+
$this->assertSame(500, $response->getStatusCode());
27+
$this->stringContains('"default" firewall requires a user provider but none was defined.', $response->getContent());
2628
}
2729
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/ExceptionController.php

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@
1212
return [
1313
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
1414
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
15-
new Symfony\Bundle\TwigBundle\TwigBundle(),
1615
new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\JsonLoginBundle\JsonLoginBundle(),
1716
];

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
imports:
2-
- { resource: ./../config/default.yml }
2+
- { resource: ./../config/framework.yml }
33

44
security:
55
encoders:

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/custom_handlers.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
imports:
2-
- { resource: ./../config/default.yml }
2+
- { resource: ./../config/framework.yml }
33

44
security:
55
encoders:

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
twig:
33
debug: '%kernel.debug%'
44
strict_variables: '%kernel.debug%'
5-
exception_controller: Symfony\Bundle\SecurityBundle\Tests\Functional\app\ExceptionController
5+
exception_controller: null # to be removed in 5.0

src/Symfony/Bundle/TwigBundle/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ CHANGELOG
77
* marked the `TemplateIterator` as `internal`
88
* added HTML comment to beginning and end of `exception_full.html.twig`
99
* added a new `TwigHtmlErrorRenderer` for `html` format, integrated with the `ErrorRenderer` component
10-
* deprecated `ExceptionController` class and all built-in error templates in favor of the new error renderer mechanism
11-
* deprecated default value `twig.controller.exception::showAction` of `twig.exception_controller` configuration option, set it to `null` instead
10+
* deprecated `ExceptionController` and `PreviewErrorController` controllers, use `ErrorController` from the `HttpKernel` component instead
11+
* deprecated all built-in error templates in favor of the new error renderer mechanism
12+
* deprecated `twig.exception_controller` configuration option, set it to "null" and use `framework.error_controller` configuration instead
1213

1314
4.2.0
1415
-----

src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use Twig\Error\LoaderError;
2020
use Twig\Loader\ExistsLoaderInterface;
2121

22-
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use the ErrorRenderer component instead.', ExceptionController::class), E_USER_DEPRECATED);
22+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ExceptionController::class, \Symfony\Component\HttpKernel\Controller\ErrorController::class), E_USER_DEPRECATED);
2323

2424
/**
2525
* ExceptionController renders error or exception pages for a given
2828
* @author Fabien Potencier <fabien@symfony.com>
2929
* @author Matthias Pigulla <mp@webfactory.de>
3030
*
31-
* @deprecated since Symfony 4.4, use the ErrorRenderer component instead.
31+
* @deprecated since Symfony 4.4, use Symfony\Component\HttpKernel\Controller\ErrorController instead.
3232
*/
3333
class ExceptionController
3434
{

src/Symfony/Bundle/TwigBundle/Controller/PreviewErrorController.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,35 @@
1111

1212
namespace Symfony\Bundle\TwigBundle\Controller;
1313

14-
use Symfony\Component\ErrorRenderer\ErrorRenderer;
1514
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
1615
use Symfony\Component\HttpFoundation\Request;
17-
use Symfony\Component\HttpFoundation\Response;
1816
use Symfony\Component\HttpKernel\HttpKernelInterface;
1917

18+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use the "%s" instead.', PreviewErrorController::class, \Symfony\Component\HttpKernel\Controller\ErrorController::class), E_USER_DEPRECATED);
19+
2020
/**
2121
* PreviewErrorController can be used to test error pages.
2222
*
2323
* It will create a test exception and forward it to another controller.
2424
*
2525
* @author Matthias Pigulla <mp@webfactory.de>
26+
*
27+
* @deprecated since Symfony 4.4, use the Symfony\Component\HttpKernel\Controller\ErrorController instead.
2628
*/
2729
class PreviewErrorController
2830
{
2931
protected $kernel;
3032
protected $controller;
31-
private $errorRenderer;
3233

33-
public function __construct(HttpKernelInterface $kernel, $controller, ErrorRenderer $errorRenderer = null)
34+
public function __construct(HttpKernelInterface $kernel, $controller)
3435
{
3536
$this->kernel = $kernel;
3637
$this->controller = $controller;
37-
$this->errorRenderer = $errorRenderer;
3838
}
3939

4040
public function previewErrorPageAction(Request $request, $code)
4141
{
42-
$exception = FlattenException::createFromThrowable(new \Exception('Something has intentionally gone wrong.'), $code, ['X-Debug' => false]);
43-
44-
if (null === $this->controller && null !== $this->errorRenderer) {
45-
return new Response($this->errorRenderer->render($exception, $request->getPreferredFormat()), $code);
46-
}
42+
$exception = FlattenException::createFromThrowable(new \Exception('Something has intentionally gone wrong.'), $code);
4743

4844
/*
4945
* This Request mimics the parameters set by

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExceptionListenerPass.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* Registers the Twig exception listener if Twig is registered as a templating engine.
1919
*
2020
* @author Fabien Potencier <fabien@symfony.com>
21+
*
22+
* @internal
2123
*/
2224
class ExceptionListenerPass implements CompilerPassInterface
2325
{
@@ -27,13 +29,18 @@ public function process(ContainerBuilder $container)
2729
return;
2830
}
2931

30-
// register the exception controller only if Twig is enabled and required dependencies do exist
31-
if (!class_exists('Symfony\Component\ErrorRenderer\Exception\FlattenException') || !interface_exists('Symfony\Component\EventDispatcher\EventSubscriberInterface')) {
32+
// to be removed in 5.0
33+
// register the exception listener only if it's currently used, else use the provided by FrameworkBundle
34+
if (null === $container->getParameter('twig.exception_listener.controller') && $container->hasDefinition('exception_listener')) {
3235
$container->removeDefinition('twig.exception_listener');
33-
} elseif ($container->hasParameter('templating.engines')) {
34-
$engines = $container->getParameter('templating.engines');
35-
if (!\in_array('twig', $engines)) {
36-
$container->removeDefinition('twig.exception_listener');
36+
} else {
37+
$container->removeDefinition('exception_listener');
38+
39+
if ($container->hasParameter('templating.engines')) {
40+
$engines = $container->getParameter('templating.engines');
41+
if (!\in_array('twig', $engines, true)) {
42+
$container->removeDefinition('twig.exception_listener');
43+
}
3744
}
3845
}
3946
}

src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,18 @@ public function getConfigTreeBuilder()
3636
->children()
3737
->scalarNode('exception_controller')
3838
->defaultValue(static function () {
39-
@trigger_error('Relying on the default value ("twig.controller.exception::showAction") of the "twig.exception_controller" configuration option is deprecated since Symfony 4.4, set it to "null" explicitly instead, which will be the new default in 5.0.', E_USER_DEPRECATED);
39+
@trigger_error('The "twig.exception_controller" configuration key has been deprecated in Symfony 4.4, set it to "null" and use "framework.error_controller" configuration key instead.', E_USER_DEPRECATED);
4040

4141
return 'twig.controller.exception::showAction';
4242
})
43+
->validate()
44+
->ifTrue(static function ($v) { return null !== $v; })
45+
->then(static function ($v) {
46+
@trigger_error('The "twig.exception_controller" configuration key has been deprecated in Symfony 4.4, set it to "null" and use "framework.error_controller" configuration key instead.', E_USER_DEPRECATED);
47+
48+
return $v;
49+
})
50+
->end()
4351
->end()
4452
->end()
4553
;

src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
<argument>%twig.exception_listener.controller%</argument>
135135
<argument type="service" id="logger" on-invalid="null" />
136136
<argument>%kernel.debug%</argument>
137+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4.</deprecated>
137138
</service>
138139

139140
<service id="twig.controller.exception" class="Symfony\Bundle\TwigBundle\Controller\ExceptionController" public="true">
@@ -145,7 +146,7 @@
145146
<service id="twig.controller.preview_error" class="Symfony\Bundle\TwigBundle\Controller\PreviewErrorController" public="true">
146147
<argument type="service" id="http_kernel" />
147148
<argument>%twig.exception_listener.controller%</argument>
148-
<argument type="service" id="error_renderer" on-invalid="null" />
149+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4.</deprecated>
149150
</service>
150151

151152
<service id="twig.configurator.environment" class="Symfony\Bundle\TwigBundle\DependencyInjection\Configurator\EnvironmentConfigurator">

0 commit comments

Comments
 (0)
0