Skip to content

Commit

Permalink
feature #12330 [Debug] DI controllable ErrorHandler::register() (nico…
Browse files Browse the repository at this point in the history
…las-grekas)

This PR was merged into the 2.6-dev branch.

Discussion
----------

[Debug] DI controllable ErrorHandler::register()

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #12327
| License       | MIT
| Doc PR        | -

This enhances the `ErrorHandler::register()` signature in a BC way, allowing greater control.

See https://github.com/symfony/symfony/pull/12330/files?w=1

Commits
-------

417f021 [Debug] DI controllable ErrorHandler::register()
  • Loading branch information
fabpot committed Nov 2, 2014
2 parents 50bc516 + 417f021 commit 0588f0e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class FrameworkBundle extends Bundle
{
public function boot()
{
ErrorHandler::register($this->container->getParameter('debug.error_handler.throw_at'));
ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true);

if ($trustedProxies = $this->container->getParameter('kernel.trusted_proxies')) {
Request::setTrustedProxies($trustedProxies);
Expand Down
39 changes: 26 additions & 13 deletions src/Symfony/Component/Debug/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,42 @@ class ErrorHandler
/**
* Registers the error handler.
*
* @param int $levels Levels to register to for throwing, 0 for none
* @param bool $throw @deprecated argument, same as setting $levels to 0
* @param self|null|int $handler The handler to register, or @deprecated (since 2.6, to be removed in 3.0) bit field of thrown levels
* @param bool $replace Whether to replace or not any existing handler
*
* @return ErrorHandler The registered error handler
* @return self The registered error handler
*/
public static function register($levels = -1, $throw = true)
public static function register($handler = null, $replace = true)
{
if (null === self::$reservedMemory) {
self::$reservedMemory = str_repeat('x', 10240);
register_shutdown_function(__CLASS__.'::handleFatalError');
}

$handler = new static();
$levels &= $handler->thrownErrors;
$prev = set_error_handler(array($handler, 'handleError'), $levels);
$prev = is_array($prev) ? $prev[0] : null;
if ($prev instanceof self) {
restore_error_handler();
$handler = $prev;
} else {
$levels = -1;

if ($handlerIsNew = !$handler instanceof self) {
// @deprecated polymorphism, to be removed in 3.0
if (null !== $handler) {
$levels = $replace ? $handler : 0;
$replace = true;
}
$handler = new static();
}

$prev = set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);

if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) {
$handler = $prev[0];
$replace = false;
}
if ($replace || !$prev) {
$handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
} else {
restore_error_handler();
}
$handler->throwAt($throw ? $levels : 0, true);

$handler->throwAt($levels & $handler->thrownErrors, true);

return $handler;
}
Expand Down
47 changes: 35 additions & 12 deletions src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,28 @@ public function testRegister()

try {
$this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
$this->assertSame($handler, ErrorHandler::register());

$newHandler = new ErrorHandler();

$this->assertSame($newHandler, ErrorHandler::register($newHandler, false));
$h = set_error_handler('var_dump');
restore_error_handler();
$this->assertSame(array($handler, 'handleError'), $h);

try {
$this->assertSame($handler, ErrorHandler::register());
} catch (\Exception $e) {
$this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
$h = set_error_handler('var_dump');
restore_error_handler();
restore_exception_handler();
$this->assertSame(array($newHandler, 'handleError'), $h);
} catch (\Exception $e) {
}

restore_error_handler();
restore_exception_handler();

if (isset($e)) {
throw $e;
}
} catch (\Exception $e) {
}
Expand Down Expand Up @@ -121,7 +137,9 @@ private static function triggerNotice($that)
public function testConstruct()
{
try {
$this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, ErrorHandler::register(3)->throwAt(0));
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));

restore_error_handler();
restore_exception_handler();
Expand Down Expand Up @@ -175,19 +193,22 @@ public function testDefaultLogger()
public function testHandleError()
{
try {
$handler = ErrorHandler::register(0);
$handler = ErrorHandler::register();
$handler->throwAt(0, true);
$this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register(3);
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register(3);
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
try {
$handler->handleError(4, 'foo', 'foo.php', 12, array());
} catch (\ErrorException $e) {
Expand All @@ -200,13 +221,15 @@ public function testHandleError()
restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register(E_USER_DEPRECATED);
$handler = ErrorHandler::register();
$handler->throwAt(E_USER_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register(E_DEPRECATED);
$handler = ErrorHandler::register();
$handler->throwAt(E_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, array()));

restore_error_handler();
Expand All @@ -230,7 +253,7 @@ public function testHandleError()
->will($this->returnCallback($warnArgCheck))
;

$handler = ErrorHandler::register(E_USER_DEPRECATED);
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_USER_DEPRECATED);
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));

Expand All @@ -252,7 +275,7 @@ public function testHandleError()
->will($this->returnCallback($logArgCheck))
;

$handler = ErrorHandler::register(E_NOTICE);
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->screamAt(E_NOTICE);
unset($undefVar);
Expand Down Expand Up @@ -357,7 +380,7 @@ public function testHandleFatalError()
}
}

public function testDeprecated()
public function testDeprecatedInterface()
{
try {
$handler = ErrorHandler::register(0);
Expand Down

0 comments on commit 0588f0e

Please sign in to comment.