From 8f426c0c772ea08881f7b7b86119a775c2a03ade Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 12 May 2011 17:49:11 +0200 Subject: [PATCH] [HttpKernel] added an exception handler to be used during boot time This can be used as a PHP exception handler: set_exception_handler(new DebugExceptionHandler()); --- .../Debug/DebugExceptionHandler.php | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/Symfony/Component/HttpKernel/Debug/DebugExceptionHandler.php diff --git a/src/Symfony/Component/HttpKernel/Debug/DebugExceptionHandler.php b/src/Symfony/Component/HttpKernel/Debug/DebugExceptionHandler.php new file mode 100644 index 000000000000..28507052ec47 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Debug/DebugExceptionHandler.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Debug; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\FlattenException; + +/** + * DebugExceptionHandler converts an exception to a Response object. + * + * It is mostly useful in debug mode to replace the default PHP/XDebug + * output with something prettier and more useful. + * + * As this class is mainly used during Kernel boot, where nothing is yet + * available, the Response content is always HTML. + * + * @author Fabien Potencier + */ +class DebugExceptionHandler +{ + /** + * Returns a Response for the given Exception. + * + * @param \Exception $exception An \Exception instance + * + * @return Response A Response instance + */ + public function handle(\Exception $exception) + { + $exception = FlattenException::create($exception); + + return new Response($this->decorate($exception, $this->getContent($exception)), 500); + } + + public function __invoke(\Exception $exception) + { + $this->handle($exception)->send(); + } + + private function getContent($exception) + { + $message = nl2br($exception->getMessage()); + $class = $this->abbrClass($exception->getClass()); + $count = count($exception->getAllPrevious()); + $content = ''; + foreach ($exception->toArray() as $position => $e) { + $ind = $count - $position + 1; + $total = $count + 1; + $class = $this->abbrClass($e['class']); + $message = nl2br($e['message']); + $content .= "

$ind/$total $class: $message

    "; + foreach ($e['trace'] as $i => $trace) { + $content .= '
  1. '; + if ($trace['function']) { + $content .= sprintf('at %s%s%s()', $this->abbrClass($trace['class']), $trace['type'], $trace['function']); + } + if (isset($trace['file']) && isset($trace['line'])) { + $content .= sprintf(' in %s line %s', $trace['file'], $trace['line']); + } + $content .= '
  2. '; + } + + $content .= '
'; + } + + return '
'.$content.'
'; + } + + private function decorate($exception, $content) + { + $title = sprintf('%s (%s %s)', $exception->getMessage(), $exception->getStatusCode(), Response::$statusTexts[$exception->getStatusCode()]); + + return << + + + + + {$title} + + + +
+ $content +
+ + +EOF; + } + + private function abbrClass($class) + { + $parts = explode('\\', $class); + + return sprintf("%s", $class, array_pop($parts)); + } +}