Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit aec873b

Browse filesBrowse files
committed
[HttpKernel] Add support for configuration log, logLevel, and status code by exception classx
1 parent cbe1f81 commit aec873b
Copy full SHA for aec873b

File tree

4 files changed

+77
-9
lines changed
Filter options

4 files changed

+77
-9
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\Common\Annotations\PsrCachedReader;
1616
use Doctrine\Common\Cache\Cache;
1717
use Doctrine\DBAL\Connection;
18+
use Psr\Log\LogLevel;
1819
use Symfony\Bundle\FullStack;
1920
use Symfony\Component\Asset\Package;
2021
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
@@ -139,6 +140,7 @@ public function getConfigTreeBuilder()
139140
$this->addPropertyInfoSection($rootNode, $enableIfStandalone);
140141
$this->addCacheSection($rootNode, $willBeAvailable);
141142
$this->addPhpErrorsSection($rootNode);
143+
$this->addExceptionsSection($rootNode);
142144
$this->addWebLinkSection($rootNode, $enableIfStandalone);
143145
$this->addLockSection($rootNode, $enableIfStandalone);
144146
$this->addMessengerSection($rootNode, $enableIfStandalone);
@@ -1155,6 +1157,44 @@ private function addPhpErrorsSection(ArrayNodeDefinition $rootNode)
11551157
;
11561158
}
11571159

1160+
private function addExceptionsSection(ArrayNodeDefinition $rootNode)
1161+
{
1162+
$logLevels = (new \ReflectionClass(LogLevel::class))->getConstants();
1163+
1164+
$rootNode
1165+
->children()
1166+
->arrayNode('exceptions')
1167+
->info('Exception handling configuration')
1168+
// ->defaultValue([])
1169+
->prototype('array')
1170+
->children()
1171+
->booleanNode('log')
1172+
->info('Log the exception')
1173+
->defaultTrue()
1174+
->end()
1175+
->scalarNode('logLevel')
1176+
->info('The level of log message. Null to let Symfony decide.')
1177+
->validate()
1178+
->ifTrue(function ($v) use ($logLevels) { return !\in_array($v, $logLevels); })
1179+
->thenInvalid(sprintf('The log level is not valid. Pick one among "%s".', implode('", "', $logLevels)))
1180+
->end()
1181+
->defaultNull()
1182+
->end()
1183+
->scalarNode('statusCode')
1184+
->info('The status code of the response. Null to let Symfony decide.')
1185+
->validate()
1186+
->ifTrue(function ($v) { return !\in_array($v, range(100, 499));})
1187+
->thenInvalid('The log level is not valid. Pick one among between 100 et 599.')
1188+
->end()
1189+
->defaultNull()
1190+
->end()
1191+
->end()
1192+
->end()
1193+
->end()
1194+
->end()
1195+
;
1196+
}
1197+
11581198
private function addLockSection(ArrayNodeDefinition $rootNode, callable $enableIfStandalone)
11591199
{
11601200
$rootNode

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ public function load(array $configs, ContainerBuilder $container)
423423
$this->registerPropertyAccessConfiguration($config['property_access'], $container, $loader);
424424
$this->registerSecretsConfiguration($config['secrets'], $container, $loader);
425425

426+
$container->getDefinition('exception_listener')->replaceArgument(3, $config['exceptions']);
427+
426428
if ($this->isConfigEnabled($container, $config['serializer'])) {
427429
if (!class_exists(\Symfony\Component\Serializer\Serializer::class)) {
428430
throw new LogicException('Serializer support cannot be enabled as the Serializer component is not installed. Try running "composer require symfony/serializer-pack".');

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/web.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/web.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
param('kernel.error_controller'),
103103
service('logger')->nullOnInvalid(),
104104
param('kernel.debug'),
105+
abstract_arg('an exceptions to log & status code mapping'),
105106
])
106107
->tag('kernel.event_subscriber')
107108
->tag('monolog.logger', ['channel' => 'request'])

‎src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php
+34-9Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,35 @@ class ErrorListener implements EventSubscriberInterface
3232
protected $controller;
3333
protected $logger;
3434
protected $debug;
35+
protected $exceptionsMapping;
3536

36-
public function __construct($controller, LoggerInterface $logger = null, bool $debug = false)
37+
public function __construct($controller, LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = [])
3738
{
3839
$this->controller = $controller;
3940
$this->logger = $logger;
4041
$this->debug = $debug;
42+
$this->exceptionsMapping = $exceptionsMapping;
4143
}
4244

4345
public function logKernelException(ExceptionEvent $event)
4446
{
45-
$e = FlattenException::createFromThrowable($event->getThrowable());
47+
$throwable = $event->getThrowable();
48+
$logLevel = null;
49+
foreach ($this->exceptionsMapping as $exception => $config) {
50+
if (!$throwable instanceof $exception) {
51+
continue;
52+
}
53+
54+
if (!$config['log']) {
55+
return;
56+
}
57+
$logLevel = $config['logLevel'];
58+
break;
59+
}
4660

47-
$this->logException($event->getThrowable(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
61+
$e = FlattenException::createFromThrowable($throwable);
62+
63+
$this->logException($throwable, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()), $logLevel);
4864
}
4965

5066
public function onKernelException(ExceptionEvent $event)
@@ -53,8 +69,8 @@ public function onKernelException(ExceptionEvent $event)
5369
return;
5470
}
5571

56-
$exception = $event->getThrowable();
57-
$request = $this->duplicateRequest($exception, $event->getRequest());
72+
$throwable = $event->getThrowable();
73+
$request = $this->duplicateRequest($throwable, $event->getRequest());
5874

5975
try {
6076
$response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false);
@@ -65,18 +81,25 @@ public function onKernelException(ExceptionEvent $event)
6581

6682
$prev = $e;
6783
do {
68-
if ($exception === $wrapper = $prev) {
84+
if ($throwable === $wrapper = $prev) {
6985
throw $e;
7086
}
7187
} while ($prev = $wrapper->getPrevious());
7288

7389
$prev = new \ReflectionProperty($wrapper instanceof \Exception ? \Exception::class : \Error::class, 'previous');
7490
$prev->setAccessible(true);
75-
$prev->setValue($wrapper, $exception);
91+
$prev->setValue($wrapper, $throwable);
7692

7793
throw $e;
7894
}
7995

96+
foreach ($this->exceptionsMapping as $exception => $config) {
97+
if ($throwable instanceof $exception) {
98+
$response->setStatusCode($config['statusCode']);
99+
break;
100+
}
101+
}
102+
80103
$event->setResponse($response);
81104

82105
if ($this->debug) {
@@ -124,10 +147,12 @@ public static function getSubscribedEvents(): array
124147
/**
125148
* Logs an exception.
126149
*/
127-
protected function logException(\Throwable $exception, string $message): void
150+
protected function logException(\Throwable $exception, string $message, ?string $logLevel = null): void
128151
{
129152
if (null !== $this->logger) {
130-
if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
153+
if (null !== $logLevel) {
154+
$this->logger->log($logLevel, $message, ['exception' => $exception]);
155+
} elseif (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
131156
$this->logger->critical($message, ['exception' => $exception]);
132157
} else {
133158
$this->logger->error($message, ['exception' => $exception]);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.