/** * Returns the statically rendered exception message * * @param integer $statusCode * @param object $exception \Exception or \Throwable * @return void */ protected function renderStatically($statusCode, $exception) { $statusMessage = Response::getStatusMessageByCode($statusCode); $exceptionHeader = ''; while (true) { $pathPosition = strpos($exception->getFile(), 'Packages/'); $filePathAndName = $pathPosition !== false ? substr($exception->getFile(), $pathPosition) : $exception->getFile(); $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : ''; $exceptionMessageParts = $this->splitExceptionMessage($exception->getMessage()); $exceptionHeader .= '<h2 class="ExceptionSubject">' . $exceptionCodeNumber . htmlspecialchars($exceptionMessageParts['subject']) . '</h2>'; if ($exceptionMessageParts['body'] !== '') { $exceptionHeader .= '<p class="ExceptionBody">' . nl2br(htmlspecialchars($exceptionMessageParts['body'])) . '</p>'; } $exceptionHeader .= ' <span class="ExceptionProperty">' . get_class($exception) . '</span> thrown in file<br /> <span class="ExceptionProperty">' . $filePathAndName . '</span> in line <span class="ExceptionProperty">' . $exception->getLine() . '</span>.<br />'; if ($exception instanceof FlowException) { $exceptionHeader .= '<span class="ExceptionProperty">Reference code: ' . $exception->getReferenceCode() . '</span><br />'; } if ($exception->getPrevious() === null) { break; } $exceptionHeader .= '<br /><div style="width: 100%; background-color: #515151; color: white; padding: 2px; margin: 0 0 6px 0;">Nested Exception</div>'; $exception = $exception->getPrevious(); } $backtraceCode = Debugger::getBacktraceCode($exception->getTrace()); echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> <head> <title>' . $statusCode . ' ' . $statusMessage . '</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style> .ExceptionSubject { margin: 0; padding: 0; font-size: 15px; color: #BE0027; } .ExceptionBody { padding: 10px; margin: 10px; color: black; background: #DDD; } .ExceptionProperty { color: #101010; } pre { margin: 0; font-size: 11px; color: #515151; background-color: #D0D0D0; padding-left: 30px; } </style> </head> <div style=" position: absolute; left: 10px; background-color: #B9B9B9; outline: 1px solid #515151; color: #515151; font-family: Arial, Helvetica, sans-serif; font-size: 12px; margin: 10px; padding: 0; "> <div style="width: 100%; background-color: #515151; color: white; padding: 2px; margin: 0 0 6px 0;">Uncaught Exception in Flow</div> <div style="width: 100%; padding: 2px; margin: 0 0 6px 0;"> ' . $exceptionHeader . ' <br /> ' . $backtraceCode . ' </div> </div> '; }
/** * Returns the statically rendered exception message * * @param integer $statusCode * @param object $exception \Exception or \Throwable * @return void */ protected function renderStatically($statusCode, $exception) { $statusMessage = Response::getStatusMessageByCode($statusCode); $exceptionHeader = '<div class="Flow-Debug-Exception-Header">'; while (true) { $filepaths = Debugger::findProxyAndShortFilePath($exception->getFile()); $filePathAndName = $filepaths['proxy'] !== '' ? $filepaths['proxy'] : $filepaths['short']; $exceptionMessageParts = $this->splitExceptionMessage($exception->getMessage()); $exceptionHeader .= '<h1 class="ExceptionSubject">' . htmlspecialchars($exceptionMessageParts['subject']) . '</h1>'; if ($exceptionMessageParts['body'] !== '') { $exceptionHeader .= '<p class="ExceptionBody">' . nl2br(htmlspecialchars($exceptionMessageParts['body'])) . '</p>'; } $exceptionHeader .= '<table class="Flow-Debug-Exception-Meta"><tbody>'; $exceptionHeader .= '<tr><th>Exception Code</th><td class="ExceptionProperty">' . $exception->getCode() . '</td></tr>'; $exceptionHeader .= '<tr><th>Exception Type</th><td class="ExceptionProperty">' . get_class($exception) . '</td></tr>'; if ($exception instanceof FlowException) { $exceptionHeader .= '<tr><th>Log Reference</th><td class="ExceptionProperty">' . $exception->getReferenceCode() . '</td></tr>'; } $exceptionHeader .= '<tr><th>Thrown in File</th><td class="ExceptionProperty">' . $filePathAndName . '</td></tr>'; $exceptionHeader .= '<tr><th>Line</th><td class="ExceptionProperty">' . $exception->getLine() . '</td></tr>'; if ($filepaths['proxy'] !== '') { $exceptionHeader .= '<tr><th>Original File</th><td class="ExceptionProperty">' . $filepaths['short'] . '</td></tr>'; } $exceptionHeader .= '</tbody></table>'; if ($exception->getPrevious() === null) { break; } $exceptionHeader .= '<br /><h2>Nested Exception</h2>'; $exception = $exception->getPrevious(); } $exceptionHeader .= '</div>'; $backtraceCode = Debugger::getBacktraceCode($exception->getTrace()); $footer = '<div class="Flow-Debug-Exception-Footer">'; $footer .= '<table class="Flow-Debug-Exception-InstanceData"><tbody>'; if (defined('FLOW_PATH_ROOT')) { $footer .= '<tr><th>Instance root</th><td class="ExceptionProperty">' . FLOW_PATH_ROOT . '</td></tr>'; } if (Bootstrap::$staticObjectManager instanceof ObjectManagerInterface) { $bootstrap = Bootstrap::$staticObjectManager->get(Bootstrap::class); $footer .= '<tr><th>Application Context</th><td class="ExceptionProperty">' . $bootstrap->getContext() . '</td></tr>'; $footer .= '<tr><th>Request Handler</th><td class="ExceptionProperty">' . get_class($bootstrap->getActiveRequestHandler()) . '</td></tr>'; } $footer .= '</tbody></table>'; $footer .= '</div>'; echo sprintf($this->htmlExceptionTemplate, $statusCode . ' ' . $statusMessage, file_get_contents(__DIR__ . '/../../Resources/Public/Error/Exception.css'), $exceptionHeader, $backtraceCode, $footer); }
/** * Prepare a response in case an error occurred. * * @param object $exception \Exception or \Throwable * @param Http\Response $response * @return void */ protected function prepareErrorResponse($exception, Http\Response $response) { $pathPosition = strpos($exception->getFile(), 'Packages/'); $filePathAndName = $pathPosition !== false ? substr($exception->getFile(), $pathPosition) : $exception->getFile(); $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : ''; $content = PHP_EOL . 'Uncaught Exception in Flow ' . $exceptionCodeNumber . $exception->getMessage() . PHP_EOL; $content .= 'thrown in file ' . $filePathAndName . PHP_EOL; $content .= 'in line ' . $exception->getLine() . PHP_EOL . PHP_EOL; $content .= Debugger::getBacktraceCode($exception->getTrace(), false, true) . PHP_EOL; if ($exception instanceof Exception) { $statusCode = $exception->getStatusCode(); } else { $statusCode = 500; } $response->setStatus($statusCode); $response->setContent($content); $response->setHeader('X-Flow-ExceptionCode', $exception->getCode()); $response->setHeader('X-Flow-ExceptionMessage', $exception->getMessage()); }
/** * Renders background information about the circumstances of the exception. * * @param string $message * @param array $backTrace * @return string */ protected function renderBacktrace($message, $backTrace) { return $message . PHP_EOL . PHP_EOL . Debugger::getBacktraceCode($backTrace, false, true); }