public function testException() { $message = 'THIS IS THE ERROR MESSAGE'; $e = new \Exception($message); $this->assertStringMatchesFormat("%A{$message}%A", HtmlUtilities::exception($e)); $this->assertStringMatchesFormat("%A{$message}%A", HtmlUtilities::exception(FlattenException::create($e))); }
public function handle(Event $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event->getParameter('request_type')) { return false; } $exception = $event->getParameter('exception'); $request = $event->getParameter('request'); if (null !== $this->logger) { $this->logger->err(sprintf('%s: %s (uncaught exception)', get_class($exception), $exception->getMessage())); } else { error_log(sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); } $logger = null !== $this->logger ? $this->logger->getDebugLogger() : null; $attributes = array('_controller' => $this->controller, 'exception' => FlattenException::create($exception), 'logger' => $logger, 'format' => 0 === strncasecmp(PHP_SAPI, 'cli', 3) ? 'txt' : $request->getRequestFormat()); $request = $request->duplicate(null, null, $attributes); try { $response = $event->getSubject()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { if (null !== $this->logger) { $this->logger->err(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage())); } // re-throw the exception as this is a catch-all throw new \RuntimeException('Exception thrown when handling an exception.', 0, $e); } $event->setReturnValue($response); return true; }
/** * @dataProvider flattenDataProvider */ public function testFlattenHttpException(\Exception $exception, $statusCode) { $flattened = FlattenException::create($exception); $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.'); $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.'); $this->assertEquals(get_class($exception), $flattened->getClass(), 'The class is set to the class of the original exception'); }
/** * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event */ public function onKernelException(\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) { if ($this->logger === null || $this->container->get('kernel')->getEnvironment() == 'dev') { return; } $exception = $event->getException(); if ($exception) { $flattenException = \Symfony\Component\HttpKernel\Exception\FlattenException::create($exception); echo $this->getContent($flattenException, $clientInfo); exit; // remove if condition to send 404 error mails also if ($flattenException->getStatusCode() != '404') { $clientInfo = '<pre>' . print_r($_SERVER, true) . '</pre>'; $message = \Swift_Message::newInstance()->setSubject($this->container->getParameter('error_email_subject'))->setFrom($this->container->getParameter('error_email_from'))->setTo($this->container->getParameter('error_email_to'))->setBody($this->decorate($this->getContent($flattenException, $clientInfo), $this->getStylesheet($flattenException)), 'text/html'); $this->container->get('mailer')->send($message); } } if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) { if ('The website you are looking is either disabled or not found!' == $exception->getMessage()) { $response = new Response($this->container->get('twig')->render(new TemplateReference('TwigBundle', 'Exception', 'errorDisabled', 'html', 'twig'), array('status_code' => 404, 'status_text' => isset(Response::$statusTexts[404]) ? Response::$statusTexts[404] : '', 'exception' => $exception, 'logger' => null, 'currentContent' => null))); $event->setResponse($response); return; } } }
/** * Creates the error Response associated with the given Exception. * * @param \Exception|FlattenException $exception An \Exception instance * * @return Response A Response instance */ public function createResponse($exception) { $content = ''; $title = ''; try { if (!$exception instanceof FlattenException) { $exception = FlattenException::create($exception); } switch ($exception->getStatusCode()) { case 404: $title = 'Sorry, the page you are looking for could not be found.'; break; default: $title = 'Whoops, looks like something went wrong.'; } if ($this->debug) { $content = $this->getContent($exception); } } catch (\Exception $e) { // something nasty happened and we cannot throw an exception here anymore if ($this->debug) { $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage()); } else { $title = 'Whoops, looks like something went wrong.'; } } return new Response($this->decorate($content, $title), $exception->getStatusCode()); }
/** * Creates the error Response associated with the given Exception. * * @param \Exception|FlattenException $exception An \Exception instance * * @return Response A Response instance */ public function createResponse($exception) { if (!$exception instanceof FlattenException) { $exception = FlattenException::create($exception); } return new Response($this->decorate($this->getContent($exception), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders()); }
public function onKernelException(GetResponseForExceptionEvent $event) { static $handling; if (true === $handling) { return false; } $handling = true; $exception = $event->getException(); $request = $event->getRequest(); $this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); $attributes = array('_controller' => $this->controller, 'exception' => FlattenException::create($exception), 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, 'format' => $request->getRequestFormat()); $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { $this->logException($exception, sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()), false); // set handling to false otherwise it wont be able to handle further more $handling = false; // re-throw the exception from within HttpKernel as this is a catch-all return; } $event->setResponse($response); $handling = false; }
private function saveDebugInformation(\Exception $ex = null) { if (!$this->input->hasOption('jms-job-id') || null === ($jobId = $this->input->getOption('jms-job-id'))) { return; } $this->getConnection()->executeUpdate("UPDATE jms_jobs SET stackTrace = :trace, memoryUsage = :memoryUsage, memoryUsageReal = :memoryUsageReal WHERE id = :id", array('id' => $jobId, 'memoryUsage' => memory_get_peak_usage(), 'memoryUsageReal' => memory_get_peak_usage(true), 'trace' => serialize($ex ? FlattenException::create($ex) : null))); }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = null) { if (null !== $exception) { $this->data = array( 'exception' => FlattenException::create($exception), ); } }
public function testCollect() { $e = new \Exception('foo', 500); $c = new ExceptionStatsCollector('prefix', $this->mockStatsDFactory('prefix.exception.500')); $flattened = FlattenException::create($e); $trace = $flattened->getTrace(); $c->collect(new Request(), new Response(), $e); }
public function testRecursionInArguments() { $a = array('foo', array(2, &$a)); $exception = $this->createException($a); $flattened = FlattenException::create($exception); $trace = $flattened->getTrace(); $this->assertContains('*DEEP NESTED ARRAY*', serialize($trace)); }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = null) { if (null !== $exception) { $flattenException = FlattenException::create($exception); if ($exception instanceof HttpExceptionInterface) { $flattenException->setStatusCode($exception->getStatusCode()); } $this->data = array('exception' => $flattenException); } }
public function testFallbackToHtmlIfNoTemplateForRequestedFormat() { $twig = new \Twig_Environment(new \Twig_Loader_Array(array('TwigBundle:Exception:error.html.twig' => 'html'))); $request = Request::create('whatever'); $request->setRequestFormat('txt'); $exception = FlattenException::create(new \Exception()); $controller = new ExceptionController($twig, false); $response = $controller->showAction($request, $exception); $this->assertEquals('html', $request->getRequestFormat()); }
public function previewErrorPageAction(Request $request, $code) { $exception = FlattenException::create(new \Exception("Something has intentionally gone wrong."), $code); /* * This Request mimics the parameters set by * \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with * the additional "showException" flag. */ $subRequest = $request->duplicate(null, null, array('_controller' => $this->controller, 'exception' => $exception, 'logger' => null, 'format' => $request->getRequestFormat(), 'showException' => false)); return $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST); }
/** * Returns a Response for the given Exception. * * @param \Exception $exception An \Exception instance * * @return Response A Response instance */ public function handle(\Exception $exception) { try { $exception = FlattenException::create($exception); $response = new Response($this->decorate($exception, $this->getContent($exception)), 500); $response->send(); } catch (\Exception $e) { // something nasty happened and we cannot throw an exception here anymore printf('Exception thrown when handling an exception (%s: %s)', get_class($exception), $exception->getMessage()); } }
/** * {@inheritdoc} */ public function render(\Exception $exception, BlockInterface $block, Response $response = null) { $response = $response ?: new Response(); // enforce debug mode or ignore silently if (!$this->debug) { return $response; } $flattenException = FlattenException::create($exception); $code = $flattenException->getStatusCode(); $parameters = array('exception' => $flattenException, 'status_code' => $code, 'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', 'logger' => false, 'currentContent' => false, 'block' => $block, 'forceStyle' => $this->forceStyle); $content = $this->templating->render($this->template, $parameters); $response->setContent($content); return $response; }
public function onKernelException(GetResponseForExceptionEvent $event) { static $handling; if (true === $handling) { return false; } $handling = true; $exception = $event->getException(); $request = $event->getRequest(); if (null !== $this->logger) { $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()); if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) { $this->logger->crit($message); } else { $this->logger->err($message); } } else { error_log(sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); } $logger = $this->logger instanceof DebugLoggerInterface ? $this->logger : null; $flattenException = FlattenException::create($exception); if ($exception instanceof HttpExceptionInterface) { $flattenException->setStatusCode($exception->getStatusCode()); $flattenException->setHeaders($exception->getHeaders()); } $attributes = array('_controller' => $this->controller, 'exception' => $flattenException, 'logger' => $logger, 'format' => $request->getRequestFormat()); $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { $message = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()); if (null !== $this->logger) { if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) { $this->logger->crit($message); } else { $this->logger->err($message); } } else { error_log($message); } // set handling to false otherwise it wont be able to handle further more $handling = false; // re-throw the exception as this is a catch-all throw $exception; } $event->setResponse($response); $handling = false; }
public function testCollect() { $e = new \Exception('foo', 500); $c = new ExceptionDataCollector(); $flattened = FlattenException::create($e); $trace = $flattened->getTrace(); $this->assertFalse($c->hasException()); $c->collect(new Request(), new Response(), $e); $this->assertTrue($c->hasException()); $this->assertEquals($flattened, $c->getException()); $this->assertSame('foo', $c->getMessage()); $this->assertSame(500, $c->getCode()); $this->assertSame('exception', $c->getName()); $this->assertSame($trace, $c->getTrace()); }
/** * @dataProvider flattenDataProvider */ public function testToArray(\Exception $exception, $statusCode) { $flattened = FlattenException::create($exception); $flattened->setTrace(array(),'foo.php',123); $this->assertEquals(array( array( 'message'=> 'test', 'class'=>'Exception', 'trace'=>array(array( 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', 'file' => 'foo.php','line' => 123, 'args' => array() )), ) ),$flattened->toArray()); }
/** * Handles a kernel exception and returns a relevant response. * Aims to deliver content to the user that explains the exception, rather than falling * back on symfony's exception handler which displays a less verbose error message. * * @param GetResponseForExceptionEvent $event The exception event */ public function onKernelException(GetResponseForExceptionEvent $event) { // do nothing if request is no preview request if (!$event->getRequest()->get('preview', false)) { return; } $ex = $event->getException(); $code = 500; $previousContent = $event->getResponse(); $content = $previousContent !== null ? $previousContent->getContent() : ''; $statusTexts = Response::$statusTexts; $statusText = isset($statusTexts[$code]) ? $statusTexts[$code] : ''; $exception = FlattenException::create($ex, $code); // log exception $this->logger->error(sprintf('%s (%s %s)', $ex->getMessage(), $code, $statusText)); $responseContent = $this->templateEngine->render($this->findTemplate(), ['status_code' => $code, 'status_text' => $statusText, 'exception' => $exception, 'logger' => null, 'currentContent' => $content]); $event->setResponse(new Response($responseContent)); }
public function handle(\Exception $exception) { try { try { $request = $this->finder->find('Symfony\\Component\\HttpFoundation\\Request', $exception); } catch (RuntimeException $requestRetrievalFailed) { $request = Request::createFromGlobals(); } $origException = $exception; $exception = FlattenException::create($exception); $codeHelper = new CodeHelper(null, $this->kernel->getRootDir()); $title = $exception->getMessage() . ' (500 Internal Server Error)'; $template = 'Exception/exception.html.php'; ob_start(); include __DIR__ . '/../Resources/views/layout.html.php'; $content = ob_get_contents(); ob_end_clean(); $event = new FilterResponseEvent(new NullHttpKernel(), $request, HttpKernelInterface::MASTER_REQUEST, new Response($content, 500)); $this->filterResponse($event, $origException); $event->getResponse()->send(); } catch (\Exception $ex) { echo "Exception while handling exception: " . $ex->getMessage(); } }
/** * @param \Exception $exception * @return bool */ protected function filterFlattenException(\Exception $exception) { if (!$exception instanceof FlattenException) { $exception = FlattenException::create($exception); } $this->_get_status_code = $exception->getStatusCode(); if ($this->_get_status_code < 500) { return true; } return false; }
public function testSetTraceIncompleteClass() { $flattened = FlattenException::create(new \Exception('test', 123)); $flattened->setTrace(array(array('file' => __FILE__, 'line' => 123, 'function' => 'test', 'args' => array(unserialize('O:14:"BogusTestClass":0:{}')))), 'foo.php', 123); $this->assertEquals(array(array('message' => 'test', 'class' => 'Exception', 'trace' => array(array('namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123, 'args' => array()), array('namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => 'test', 'file' => __FILE__, 'line' => 123, 'args' => array(array('incomplete-object', 'BogusTestClass')))))), $flattened->toArray()); }
/** * Displays the error page for arbitrary status codes and formats. * * @param Request $request The request * @param int $code The HTTP status code to show the error page for. * * @return Response * * @throws \InvalidArgumentException When the error template does not exist */ public function testErrorPageAction(Request $request, $code) { $exception = FlattenException::create(new \Exception("Something has intentionally gone wrong."), $code); return $this->createResponse($request, $exception, false); }
/** * Clones the request for the exception. * * @param \Exception $exception The thrown exception. * @param Request $request The original request. * * @return Request $request The cloned request. */ protected function duplicateRequest(\Exception $exception, Request $request) { $attributes = array('_controller' => $this->controller, 'exception' => FlattenException::create($exception), 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, 'format' => $request->getRequestFormat()); $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); return $request; }
/** * Scrub Exception. * * @return Exception */ private function scrubException($originalException) { $exception = FlattenException::create($originalException); $trace = $exception->getTrace(); foreach ($trace as $key => $item) { array_walk_recursive($item['args'], function (&$value, $key, $params) { if (is_string($value) && ($key = array_search($value, $params))) { $value = '%' . $key . '%'; } }, $this->scrubParameters); $trace[$key] = $item; } $exception->setTrace($trace, $exception->getFile(), $exception->getLine()); return $exception; }
/** * 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); $response = new Response($this->decorate($exception, $this->getContent($exception)), 500); $response->send(); }
public function handle(Event $event) { static $handling; if (true === $handling) { return false; } $handling = true; $exception = $event->get('exception'); $request = $event->get('request'); if (null !== $this->logger) { $this->logger->err(sprintf('%s: %s (uncaught exception)', get_class($exception), $exception->getMessage())); } else { error_log(sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine())); } $logger = null !== $this->logger ? $this->logger->getDebugLogger() : null; $attributes = array('_controller' => $this->controller, 'exception' => FlattenException::create($exception), 'logger' => $logger, 'format' => 0 === strncasecmp(PHP_SAPI, 'cli', 3) ? 'txt' : $request->getRequestFormat()); $request = $request->duplicate(null, null, $attributes); try { $response = $event->getSubject()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { $message = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()); if (null !== $this->logger) { $this->logger->err($message); } else { error_log($message); } throw $exception; } $event->setReturnValue($response); $handling = false; return true; }
private function getExceptionData(ExceptionDataCollector $collector) { $exception = $collector->getException(); if (!$exception instanceof FlattenException) { $exception = FlattenException::create($exception); } $data = $exception->toArray(); foreach ($data as $nb => $exData) { // skip non-public exceptions $class = new \ReflectionClass($exData['class']); if ($class->isUserDefined() && !$this->isNamespaceWhitelisted($exData['class'])) { unset($data[$nb]); continue; } // skip built-in exceptions that are thrown from a non-public class if (!$class->isUserDefined() && (!isset($exData['trace'][1]) || !$this->isNamespaceWhitelisted($exData['trace'][1]['class']))) { unset($data[$nb]); continue; } foreach ($exData['trace'] as $key => $trace) { unset($data[$nb]['trace'][$key]['namespace'], $data[$nb]['trace'][$key]['short_class']); if ('' === $trace['class']) { $public = isset($exData['trace'][$key + 1]) && $this->isNamespaceWhitelisted($exData['trace'][$key + 1]['class']); } else { $public = $this->isNamespaceWhitelisted($trace['class']); } if (!$public) { foreach ($trace as $k => $v) { if (is_array($v)) { $data[$nb]['trace'][$key][$k] = array(); } else { if (is_string($v)) { if ('' !== $v) { $data[$nb]['trace'][$key][$k] = 'XXX'; } } else { $data[$nb]['trace'][$key][$k] = 'XXX'; } } } continue; } // additional heuristics for config data handling if ('Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' === $trace['class'] && 'parseImports' === $trace['function']) { $trace['args'] = array(array('array', array()), array('string', basename($trace['args'][1][1]))); } if ('Symfony\\Component\\Yaml\\Parser' === $trace['class'] && 'parse' === $trace['function']) { $trace['args'] = array(array('string', 'XXX')); } $data[$nb]['trace'][$key]['file'] = basename($trace['file']); $data[$nb]['trace'][$key]['args'] = $this->purgeArgsRecursive($trace['args']); } } return array_values($data); }