Last active
September 21, 2016 20:40
-
-
Save geerteltink/717d8c8218ebcc3cc16b695074fa7075 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Zend Framework (http://framework.zend.com/) | |
* | |
* @see https://github.com/zendframework/zend-expressive for the canonical source repository | |
* @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) | |
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License | |
*/ | |
namespace Zend\Expressive\Container; | |
use Interop\Container\ContainerInterface; | |
use Whoops\Handler\JsonResponseHandler; | |
use Zend\Expressive\WhoopsErrorHandler; | |
use Whoops\Run as Whoops; | |
/** | |
* Create and return an instance of the whoops error handler. | |
* | |
* Register this factory as the service `Zend\Expressive\FinalHandler` in | |
* the container of your choice. | |
* | |
* This factory has optional dependencies on the following services: | |
* | |
* - 'Zend\Expressive\Template\TemplateRendererInterface', which should return an | |
* implementation of that interface. If not present, the error handler | |
* will not create templated responses. | |
* - 'config' (which should return an array or array-like object with a | |
* "zend-expressive" top-level key, and an "error_handler" subkey, | |
* containing the configuration for the error handler). | |
* | |
* This factory has required dependencies on the following services: | |
* | |
* - Zend\Expressive\Whoops, which should return a Whoops\Run instance. | |
* - Zend\Expressive\WhoopsPageHandler, which should return a | |
* Whoops\Handler\PrettyPageHandler instance. | |
* | |
* Configuration should look like the following: | |
* | |
* <code> | |
* 'zend-expressive' => [ | |
* 'error_handler' => [ | |
* 'template_404' => 'name of 404 template', | |
* 'template_error' => 'name of error template', | |
* ], | |
* ] | |
* </code> | |
* | |
* If any of the keys are missing, default values will be used. | |
* | |
* The whoops configuration can contain: | |
* | |
* <code> | |
* 'whoops' => [ | |
* 'json_exceptions' => [ | |
* 'display' => true, | |
* 'show_trace' => true, | |
* 'ajax_only' => true, | |
* ] | |
* ] | |
* </code> | |
* | |
* All values are booleans; omission of any implies boolean false. | |
*/ | |
class WhoopsErrorHandlerFactory | |
{ | |
public function __invoke(ContainerInterface $container) | |
{ | |
$template = $container->has('Zend\Expressive\Template\TemplateRendererInterface') | |
? $container->get('Zend\Expressive\Template\TemplateRendererInterface') | |
: null; | |
$config = $container->has('config') | |
? $container->get('config') | |
: []; | |
$expressiveConfig = isset($config['zend-expressive']['error_handler']) | |
? $config['zend-expressive']['error_handler'] | |
: []; | |
$whoopsConfig = isset($config['whoops']) | |
? $config['whoops'] | |
: []; | |
$whoops = $container->get('Zend\Expressive\Whoops'); | |
$whoops->pushHandler($container->get('Zend\Expressive\WhoopsPageHandler')); | |
$this->registerJsonHandler($whoops, $whoopsConfig); | |
return new WhoopsErrorHandler( | |
$whoops, | |
null, | |
$template, | |
(isset($expressiveConfig['template_404']) ? $expressiveConfig['template_404'] : 'error/404'), | |
(isset($expressiveConfig['template_error']) ? $expressiveConfig['template_error'] : 'error/error') | |
); | |
} | |
/** | |
* If configuration indicates a JsonResponseHandler, configure and register it. | |
* | |
* @param Whoops $whoops | |
* @param array|\ArrayAccess $config | |
*/ | |
private function registerJsonHandler(Whoops $whoops, $config) | |
{ | |
if (! isset($config['json_exceptions']['display']) | |
|| empty($config['json_exceptions']['display']) | |
) { | |
return; | |
} | |
$handler = new JsonResponseHandler(); | |
if (isset($config['json_exceptions']['ajax_only'])) { | |
if (method_exists(\Whoops\Util\Misc::class, 'isAjaxRequest')) { | |
// Whoops 2.x | |
if (! \Whoops\Util\Misc::isAjaxRequest()) { | |
return; | |
} | |
} elseif (method_exists($handler, 'onlyForAjaxRequests')) { | |
// Whoops 1.x | |
$handler->onlyForAjaxRequests(true); | |
} | |
} | |
if (isset($config['json_exceptions']['show_trace'])) { | |
$handler->addTraceToOutput(true); | |
} | |
$whoops->pushHandler($handler); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Zend Framework (http://framework.zend.com/) | |
* | |
* @see http://github.com/zendframework/zend-expressive for the canonical source repository | |
* @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) | |
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License | |
*/ | |
namespace Zend\Expressive; | |
use Psr\Http\Message\RequestInterface as Request; | |
use Psr\Http\Message\ResponseInterface as Response; | |
use Whoops\Handler\PrettyPageHandler; | |
use Whoops\Run as Whoops; | |
use Zend\Stratigility\Http\Request as StratigilityRequest; | |
/** | |
* Final handler with templated page capabilities plus Whoops exception reporting. | |
* | |
* Extends from TemplatedErrorHandler in order to provide templated error and 404 | |
* pages; for exceptions, it delegates to Whoops to provide a user-friendly | |
* interface for navigating an exception stack trace. | |
* | |
* @see http://filp.github.io/whoops/ | |
*/ | |
class WhoopsErrorHandler extends TemplatedErrorHandler | |
{ | |
/** | |
* Whoops runner instance to use when returning exception details. | |
* | |
* @var Whoops | |
*/ | |
private $whoops; | |
/** | |
* Whoops PrettyPageHandler; injected to allow runtime configuration with | |
* request information. | |
* | |
* @var PrettyPageHandler | |
*/ | |
private $whoopsHandler; | |
/** | |
* @param Whoops $whoops | |
* @param PrettyPageHandler $whoopsHandler | |
* @param null|Template\TemplateRendererInterface $renderer | |
* @param null|string $template404 | |
* @param null|string $templateError | |
* @param null|Response $originalResponse | |
*/ | |
public function __construct( | |
Whoops $whoops, | |
PrettyPageHandler $whoopsHandler = null, | |
Template\TemplateRendererInterface $renderer = null, | |
$template404 = 'error/404', | |
$templateError = 'error/error', | |
Response $originalResponse = null | |
) { | |
$this->whoops = $whoops; | |
$this->whoopsHandler = $whoopsHandler; | |
parent::__construct($renderer, $template404, $templateError, $originalResponse); | |
} | |
/** | |
* Handle an exception. | |
* | |
* Calls on prepareWhoopsHandler() to inject additional data tables into | |
* the generated payload, and then injects the response with the result | |
* of whoops handling the exception. | |
* | |
* @param \Throwable $exception | |
* @param Request $request | |
* @param Response $response | |
* @return Response | |
*/ | |
protected function handleException($exception, Request $request, Response $response) | |
{ | |
// Push the whoops handler if any | |
if (null !== $this->whoopsHandler) { | |
$this->whoops->pushHandler($this->whoopsHandler); | |
} | |
// Walk through all handlers | |
foreach ($this->whoops->getHandlers() as $handler) { | |
// Add fancy data for the PrettyPageHandler | |
if ($handler instanceof PrettyPageHandler) { | |
$this->prepareWhoopsHandler($request, $handler); | |
} | |
} | |
$response | |
->getBody() | |
->write($this->whoops->handleException($exception)); | |
return $response; | |
} | |
/** | |
* Prepare the Whoops page handler with a table displaying request information | |
* | |
* @param Request $request | |
* @param PrettyPageHandler $handler | |
*/ | |
private function prepareWhoopsHandler(Request $request, PrettyPageHandler $handler) | |
{ | |
if ($request instanceof StratigilityRequest) { | |
$request = $request->getOriginalRequest(); | |
} | |
$uri = $request->getUri(); | |
$handler->addDataTable('Expressive Application Request', [ | |
'HTTP Method' => $request->getMethod(), | |
'URI' => (string) $uri, | |
'Script' => $request->getServerParams()['SCRIPT_NAME'], | |
'Headers' => $request->getHeaders(), | |
'Cookies' => $request->getCookieParams(), | |
'Attributes' => $request->getAttributes(), | |
'Query String Arguments' => $request->getQueryParams(), | |
'Body Params' => $request->getParsedBody(), | |
]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment