Skip to content

Commit a84bad7

Browse files
committed
Add deprecation warning to show HttpKernel::handle() will catch throwables
1 parent 01fee75 commit a84bad7

File tree

13 files changed

+83
-5
lines changed

13 files changed

+83
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Deprecate the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and
88
`Symfony\Component\Serializer\Normalizer\PropertyNormalizer` autowiring aliases, type-hint against
99
`Symfony\Component\Serializer\Normalizer\NormalizerInterface` or implement `NormalizerAwareInterface` instead
10+
* Add option `framework.catch_all_throwables` to allow `Symfony\Component\HttpKernel\HttpKernel` to catch all kinds of `Throwable`
1011

1112
6.1
1213
---

DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public function getConfigTreeBuilder(): TreeBuilder
133133
->scalarNode('error_controller')
134134
->defaultValue('error_controller')
135135
->end()
136+
->booleanNode('catch_all_throwables')->defaultFalse()->info('HttpKernel will catch all kinds of \Throwable')->end()
136137
->end()
137138
;
138139

DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ public function load(array $configs, ContainerBuilder $container)
320320

321321
$container->getDefinition('locale_listener')->replaceArgument(3, $config['set_locale_from_accept_language']);
322322
$container->getDefinition('response_listener')->replaceArgument(1, $config['set_content_language_from_locale']);
323+
$container->getDefinition('http_kernel')->replaceArgument(4, $config['catch_all_throwables']);
323324

324325
// If the slugger is used but the String component is not available, we should throw an error
325326
if (!ContainerBuilder::willBeAvailable('symfony/string', SluggerInterface::class, ['symfony/framework-bundle'])) {

Resources/config/services.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : []
8585
service('controller_resolver'),
8686
service('request_stack'),
8787
service('argument_resolver'),
88+
false,
8889
])
8990
->tag('container.hot_path')
9091
->tag('container.preload', ['class' => HttpKernelRunner::class])

Test/ExceptionSubscriber.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Test;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
16+
use Symfony\Component\HttpKernel\KernelEvents;
17+
18+
/**
19+
* This event subscriber allows you to inspect all exceptions thrown by the application.
20+
* This is useful since the HttpKernel catches all throwables and turns them into
21+
* an HTTP response.
22+
*
23+
* This class should only be used in tests.
24+
*
25+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
26+
*/
27+
class ExceptionSubscriber implements EventSubscriberInterface
28+
{
29+
/**
30+
* @var list<\Throwable>
31+
*/
32+
private static array $exceptions = [];
33+
34+
public function onKernelException(ExceptionEvent $event)
35+
{
36+
self::$exceptions[] = $event->getThrowable();
37+
}
38+
39+
/**
40+
* @return list<\Throwable>
41+
*/
42+
public static function shiftAll(): array
43+
{
44+
$exceptions = self::$exceptions;
45+
self::$exceptions = [];
46+
47+
return $exceptions;
48+
}
49+
50+
public static function getSubscribedEvents(): array
51+
{
52+
return [
53+
KernelEvents::EXCEPTION => 'onKernelException',
54+
];
55+
}
56+
}

Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
656656
'sanitizers' => [],
657657
],
658658
'exceptions' => [],
659+
'catch_all_throwables' => false,
659660
];
660661
}
661662
}

Tests/Functional/UidTest.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
1313

14+
use Symfony\Bundle\FrameworkBundle\Test\ExceptionSubscriber;
1415
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\UidController;
1516
use Symfony\Component\Uid\Ulid;
1617
use Symfony\Component\Uid\UuidV1;
@@ -31,12 +32,16 @@ protected function setUp(): void
3132

3233
public function testArgumentValueResolverDisabled()
3334
{
34-
$this->expectException(\TypeError::class);
35-
$this->expectExceptionMessage('Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\UidController::anyFormat(): Argument #1 ($userId) must be of type Symfony\Component\Uid\UuidV1, string given');
36-
3735
$client = $this->createClient(['test_case' => 'Uid', 'root_config' => 'config_disabled.yml']);
3836

3937
$client->request('GET', '/1/uuid-v1/'.new UuidV1());
38+
$this->assertSame(500, $client->getResponse()->getStatusCode());
39+
$exceptions = ExceptionSubscriber::shiftAll();
40+
$this->assertCount(1, $exceptions);
41+
$exception = reset($exceptions);
42+
43+
$this->assertInstanceOf(\TypeError::class, $exception);
44+
$this->assertStringContainsString('Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\UidController::anyFormat(): Argument #1 ($userId) must be of type Symfony\Component\Uid\UuidV1, string given', $exception->getMessage());
4045
}
4146

4247
public function testArgumentValueResolverEnabled()

Tests/Functional/app/Uid/config_disabled.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@ framework:
55
http_method_override: false
66
uid:
77
enabled: false
8+
9+
services:
10+
Symfony\Bundle\FrameworkBundle\Test\ExceptionSubscriber:
11+
tags:
12+
- { name: kernel.event_subscriber }

Tests/Functional/app/config/framework.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ framework:
1111
enabled_locales: ['en', 'fr']
1212
session:
1313
storage_factory_id: session.storage.factory.mock_file
14+
catch_all_throwables: true
1415

1516
services:
1617
logger: { class: Psr\Log\NullLogger }

Tests/Kernel/ConcreteMicroKernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
8686
'http_method_override' => false,
8787
'secret' => '$ecret',
8888
'router' => ['utf8' => true],
89+
'catch_all_throwables' => true,
8990
]);
9091

9192
$c->setParameter('halloween', 'Have a great day!');

0 commit comments

Comments
 (0)