diff --git a/CHANGELOG.md b/CHANGELOG.md index c295535..90bc97c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## 0.4.1 - UNRELEASED + +### Fixed + +* Fixed shutdown errors handling + ## [0.4.0] ### Added diff --git a/README.md b/README.md index 0841d14..a364a3c 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ $response = $dispatcher->dispatch(new ServerRequest()); ## Options -#### `__construct(Whoops\Run $whoops = null)` +#### `__construct(Whoops\Run $whoops = null, Whoops\Util\SystemFacade $system = null)` -Allows to provide a custom `Whoops\Run` instance. If it's not defined, creates an instance automatically. +Allows to provide a custom `Whoops\Run` instance. If it's not defined, creates an instance automatically. You can provide also the `SystemFacade` used by the `Run` instance, in order to implement a special behaviour with fatal errors. #### `catchErrors(true)` diff --git a/src/Whoops.php b/src/Whoops.php index 1185d8d..5660b31 100644 --- a/src/Whoops.php +++ b/src/Whoops.php @@ -20,6 +20,11 @@ class Whoops implements MiddlewareInterface */ private $whoops; + /** + * @var SystemFacade|null + */ + private $system; + /** * @var bool Whether catch errors or not */ @@ -29,10 +34,12 @@ class Whoops implements MiddlewareInterface * Set the whoops instance. * * @param Run|null $whoops + * @param SystemFacade|null $systemFacade */ - public function __construct(Run $whoops = null) + public function __construct(Run $whoops = null, SystemFacade $system = null) { $this->whoops = $whoops; + $this->system = $system; } /** @@ -63,7 +70,7 @@ public function process(ServerRequestInterface $request, DelegateInterface $dele $level = ob_get_level(); $method = Run::EXCEPTION_HANDLER; - $whoops = $this->whoops ?: self::getWhoopsInstance($request); + $whoops = $this->whoops ?: $this->getWhoopsInstance($request); $whoops->allowQuit(false); $whoops->writeToOutput(false); @@ -72,6 +79,21 @@ public function process(ServerRequestInterface $request, DelegateInterface $dele //Catch errors means register whoops globally if ($this->catchErrors) { $whoops->register(); + + $shutdown = function () use ($whoops) { + $whoops->allowQuit(true); + $whoops->writeToOutput(true); + $whoops->sendHttpCode(true); + + $method = Run::SHUTDOWN_HANDLER; + $whoops->$method(); + }; + + if ($this->system) { + $this->system->registerShutdownFunction($shutdown); + } else { + register_shutdown_function($shutdown); + } } try { @@ -104,23 +126,14 @@ public function process(ServerRequestInterface $request, DelegateInterface $dele * * @return Run */ - private static function getWhoopsInstance(ServerRequestInterface $request) + private function getWhoopsInstance(ServerRequestInterface $request) { - $system = new SystemFacade(); - $whoops = new Run($system); - - //E_ERROR in PHP 5.x - if (!class_exists('Throwable')) { - $system->registerShutdownFunction(function () use ($whoops) { - $whoops->allowQuit(true); - $whoops->writeToOutput(true); - $whoops->sendHttpCode(true); - - $method = Run::SHUTDOWN_HANDLER; - $whoops->$method(); - }); + if (!$this->system) { + $this->system = new SystemFacade(); } + $whoops = new Run($this->system); + switch (self::getPreferredFormat($request)) { case 'json': $handler = new JsonResponseHandler(); diff --git a/tests/WhoopsTest.php b/tests/WhoopsTest.php index 19bcc90..09b7e37 100644 --- a/tests/WhoopsTest.php +++ b/tests/WhoopsTest.php @@ -22,18 +22,18 @@ function () { $this->assertNotFalse(strpos($response->getBody(), 'Error Processing Request')); } - public function testFatalError() + public function testStandardError() { $response = Dispatcher::run([ new Whoops(), function () { - new UnexistingClass(); + $a = $b; //undefined variable }, ]); $this->assertEquals(500, $response->getStatusCode()); $this->assertEquals('text/plain', $response->getHeaderLine('Content-Type')); - $this->assertNotFalse(strpos($response->getBody(), "Class 'Middlewares\\Tests\\UnexistingClass' not found")); + $this->assertNotFalse(strpos($response->getBody(), 'Undefined variable: b')); } public function testNotError()