Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1ae2789

Browse files
[Debug] Add BootstrappingLogger to buffer errors that happen before a proper logger is configured
1 parent 7f745d7 commit 1ae2789

File tree

5 files changed

+142
-3
lines changed

5 files changed

+142
-3
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Component\Debug;
13+
14+
use Psr\Log\AbstractLogger;
15+
use Psr\Log\LoggerInterface;
16+
17+
/**
18+
* A bootstrapping logger that stacks logs and flushes them when required to an other logger.
19+
*
20+
* @author Nicolas Grekas <[email protected]>
21+
*/
22+
class BootstrappingLogger extends AbstractLogger
23+
{
24+
private $logs = array();
25+
26+
public function log($level, $message, array $context = array())
27+
{
28+
$this->logs[] = array($level, $message, $context);
29+
}
30+
31+
public function flush(LoggerInterface $logger)
32+
{
33+
$logs = $this->logs;
34+
$this->logs = array();
35+
36+
foreach ($logs as $log) {
37+
$logger->log($log[0], $log[1], $log[2]);
38+
}
39+
}
40+
}

src/Symfony/Component/Debug/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
2.8.0
5+
-----
6+
7+
* added BootstrappingLogger to buffer errors that happen before a proper logger is configured
8+
* allow throwing from `__toString()` with `return trigger_error($e, E_USER_ERROR);`
9+
* deprecate ExceptionHandler::createResponse
10+
411
2.7.0
512
-----
613

src/Symfony/Component/Debug/Debug.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ public static function enable($errorReportingLevel = null, $displayErrors = true
5353
ini_set('display_errors', 1);
5454
}
5555
$handler = ErrorHandler::register();
56+
$loggers = $handler->setLoggers(array());
57+
foreach ($loggers as &$level) {
58+
$level[0] = new BootstrappingLogger();
59+
}
60+
unset($level);
61+
$handler->setLoggers($loggers);
5662
if (!$displayErrors) {
5763
$handler->throwAt(0, true);
5864
}

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function setDefaultLogger(LoggerInterface $logger, $levels = null, $repla
165165

166166
if (is_array($levels)) {
167167
foreach ($levels as $type => $logLevel) {
168-
if (empty($this->loggers[$type][0]) || $replace) {
168+
if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] instanceof BootstrappingLogger) {
169169
$loggers[$type] = array($logger, $logLevel);
170170
}
171171
}
@@ -174,7 +174,7 @@ public function setDefaultLogger(LoggerInterface $logger, $levels = null, $repla
174174
$levels = E_ALL | E_STRICT;
175175
}
176176
foreach ($this->loggers as $type => $log) {
177-
if (($type & $levels) && (empty($log[0]) || $replace)) {
177+
if (($type & $levels) && (empty($log[0]) || $replace || $log[0] instanceof BootstrappingLogger)) {
178178
$log[0] = $logger;
179179
$loggers[$type] = $log;
180180
}
@@ -215,6 +215,10 @@ public function setLoggers(array $loggers)
215215
throw new \InvalidArgumentException('Invalid logger provided');
216216
}
217217
$this->loggers[$type] = $log + $prev[$type];
218+
219+
if (($this->loggedErrors & $type) && $prev[$type][0] instanceof BootstrappingLogger) {
220+
$prev[$type][0]->flush($this->loggers[$type][0]);
221+
}
218222
}
219223
$this->reRegister($prevLogged | $this->thrownErrors);
220224

@@ -252,7 +256,7 @@ public function setExceptionHandler($handler)
252256
public function throwAt($levels, $replace = false)
253257
{
254258
$prev = $this->thrownErrors;
255-
$this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
259+
$this->thrownErrors = (E_ALL | E_STRICT) & ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
256260
if (!$replace) {
257261
$this->thrownErrors |= $prev;
258262
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Component\Debug\Tests;
13+
14+
use Psr\Log\LogLevel;
15+
use Symfony\Component\Debug\BootstrappingLogger;
16+
use Symfony\Component\Debug\ErrorHandler;
17+
18+
/**
19+
* BootstrappingLoggerTest.
20+
*
21+
* @author Nicolas Grekas <[email protected]>
22+
*/
23+
class BootstrappingLoggerTest extends \PHPUnit_Framework_TestCase
24+
{
25+
public function testFlush()
26+
{
27+
$logger = new BootstrappingLogger();
28+
29+
$context = array(
30+
'level' => 0,
31+
'type' => E_USER_NOTICE,
32+
'file' => __FILE__,
33+
'line' => 123,
34+
);
35+
36+
$logger->log(LogLevel::INFO, 'Foo message', $context);
37+
38+
$mockLogger = $this->getMock('Psr\Log\LoggerInterface');
39+
$mockLogger->expects($this->once())
40+
->method('log')
41+
->with(LogLevel::INFO, 'Foo message', $context);
42+
43+
$logger->flush($mockLogger);
44+
}
45+
46+
public function testLifecycle()
47+
{
48+
$logger = new BootstrappingLogger();
49+
50+
$handler = new ErrorHandler();
51+
$handler->setDefaultLogger($logger);
52+
53+
$handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, array());
54+
55+
$mockLogger = $this->getMock('Psr\Log\LoggerInterface');
56+
$mockLogger->expects($this->once())
57+
->method('log')
58+
->with(LogLevel::INFO, 'Foo message', $this->isType('array'));
59+
60+
$handler->setDefaultLogger($mockLogger);
61+
62+
$loggers = array(
63+
E_DEPRECATED => array($mockLogger, LogLevel::INFO),
64+
E_USER_DEPRECATED => array($mockLogger, LogLevel::INFO),
65+
E_NOTICE => array($mockLogger, LogLevel::WARNING),
66+
E_USER_NOTICE => array($mockLogger, LogLevel::WARNING),
67+
E_STRICT => array($mockLogger, LogLevel::WARNING),
68+
E_WARNING => array($mockLogger, LogLevel::WARNING),
69+
E_USER_WARNING => array($mockLogger, LogLevel::WARNING),
70+
E_COMPILE_WARNING => array($mockLogger, LogLevel::WARNING),
71+
E_CORE_WARNING => array($mockLogger, LogLevel::WARNING),
72+
E_USER_ERROR => array($mockLogger, LogLevel::CRITICAL),
73+
E_RECOVERABLE_ERROR => array($mockLogger, LogLevel::CRITICAL),
74+
E_COMPILE_ERROR => array($mockLogger, LogLevel::CRITICAL),
75+
E_PARSE => array($mockLogger, LogLevel::CRITICAL),
76+
E_ERROR => array($mockLogger, LogLevel::CRITICAL),
77+
E_CORE_ERROR => array($mockLogger, LogLevel::CRITICAL),
78+
);
79+
80+
$this->assertSame($loggers, $handler->setLoggers(array()));
81+
}
82+
}

0 commit comments

Comments
 (0)