public static function trace(Exception $exception, $output = self::EXCEPTION_TRACE_HTML) { if (Ajde::app()->hasDocument() && Ajde::app()->getDocument()->getFormat() == 'json') { $output = self::EXCEPTION_TRACE_LOG; } if ($exception instanceof ErrorException) { $type = "PHP Error " . self::getErrorType($exception->getSeverity()); } elseif ($exception instanceof Ajde_Exception) { $type = "Uncaught application exception" . ($exception->getCode() ? ' ' . $exception->getCode() : ''); } else { $type = "Uncaught PHP exception " . $exception->getCode(); } switch ($output) { case self::EXCEPTION_TRACE_HTML: if (ob_get_level()) { ob_clean(); } $traceMessage = '<ol reversed="reversed">'; self::$firstApplicationFileExpanded = false; foreach ($exception->getTrace() as $item) { $arguments = null; if (!empty($item['args'])) { ob_start(); var_dump($item['args']); $dump = ob_get_clean(); $arguments = sprintf(' with arguments: %s', $dump); } $traceMessage .= sprintf("<li><em>%s</em>%s<strong>%s</strong><br/>in %s<br/> \n", !empty($item['class']) ? $item['class'] : '<unknown class>', !empty($item['type']) ? $item['type'] : '::', !empty($item['function']) ? $item['function'] : '<unknown function>', self::embedScript(issetor($item['file'], null), issetor($item['line'], null), $arguments, false)); $traceMessage .= '</li>'; } $traceMessage .= '</ol>'; $exceptionDocumentation = ''; if ($exception instanceof Ajde_Exception && $exception->getCode()) { $exceptionDocumentation = sprintf("<div style='margin-top: 4px;'><img src='//" . Config::get('site_root') . "public/images/_core/globe_16.png' style='vertical-align: bottom;' title='Primary key' width='16' height='16' /> <a href='%s'>Documentation on error %s</a> </div>", Ajde_Core_Documentation::getUrl($exception->getCode()), $exception->getCode()); } $exceptionMessage = sprintf("<div style='background-color:#F1F1F1;background-image: url(\"//" . Config::get('site_root') . "public/images/_core/warning_48.png\"); background-repeat: no-repeat; background-position: 10px 10px; border: 1px solid silver; padding: 10px 10px 10px 70px;'><h3 style='margin:0;'>%s:</h3><h2 style='margin:0;'>%s</h2> Exception thrown in %s%s</div><h3>Trace:</h3>\n", $type, $exception->getMessage(), self::embedScript($exception->getFile(), $exception->getLine(), $arguments, false), $exceptionDocumentation); $exceptionDump = ''; if (class_exists("Ajde_Dump")) { if ($dumps = Ajde_Dump::getAll()) { $exceptionDump .= '<h2>Dumps</h2>'; foreach ($dumps as $dump) { ob_start(); var_dump($dump[0]); $exceptionDump .= ob_get_clean(); } } } $style = false; if (file_exists(MODULE_DIR . '_core/res/css/debugger/handler.css')) { $style = file_get_contents(MODULE_DIR . '_core/res/css/debugger/handler.css'); } if ($style === false) { // For shutdown() call $style = 'body {font: 13px sans-serif;} a {color: #005D9A;} a:hover {color: #9A0092;} h2 {color: #005D9A;} span > a {color: #9A0092;}'; } $style = '<style>' . $style . '</style>'; $message = $style . $exceptionDump . $exceptionMessage . $traceMessage; break; case self::EXCEPTION_TRACE_LOG: $message = 'Request ' . $_SERVER["REQUEST_URI"] . " triggered:" . PHP_EOL; $message .= sprintf("%s: %s in %s on line %s", $type, $exception->getMessage(), $exception->getFile(), $exception->getLine()); foreach (array_reverse($exception->getTrace()) as $i => $line) { $message .= PHP_EOL; $message .= $i . '. ' . issetor($line['file']) . ' on line ' . issetor($line['line']); } break; } return $message; }
/** * @param Throwable $exception * @param int $output * * @return string */ public static function trace($exception, $output = self::EXCEPTION_TRACE_HTML) { $simpleJsonTrace = false; if ($simpleJsonTrace && Ajde::app()->hasDocument() && Ajde::app()->getDocument()->getFormat() == 'json') { $output = self::EXCEPTION_TRACE_LOG; } $type = self::getTypeDescription($exception); switch ($output) { case self::EXCEPTION_TRACE_HTML: if (ob_get_level()) { ob_clean(); } $traceMessage = '<ol reversed="reversed">'; self::$firstApplicationFileExpanded = false; foreach ($exception->getTrace() as $item) { $arguments = null; if (!empty($item['args'])) { ob_start(); var_dump($item['args']); $dump = ob_get_clean(); $arguments = sprintf(' with arguments: %s', $dump); } $traceMessage .= sprintf("<li><code><em>%s</em>%s<strong>%s</strong></code><br/>in %s<br/> \n", !empty($item['class']) ? $item['class'] : '<unknown class>', !empty($item['type']) ? $item['type'] : '::', !empty($item['function']) ? $item['function'] : '<unknown function>', self::embedScript(issetor($item['file'], null), issetor($item['line'], null), $arguments, false)); $traceMessage .= '</li>'; } $traceMessage .= '</ol>'; $exceptionDocumentation = ''; if ($exception instanceof Ajde_Exception && $exception->getCode()) { $exceptionDocumentation = sprintf("<div style='margin-top: 4px;'><img src='" . config('app.rootUrl') . MEDIA_DIR . "_core/globe_16.png' style='vertical-align: bottom;' title='Primary key' width='16' height='16' /> <a href='%s'>Documentation on error %s</a> </div>", Ajde_Core_Documentation::getUrl($exception->getCode()), $exception->getCode()); } $exceptionMessage = sprintf("<summary style='background-image: url(\"" . config('app.rootUrl') . MEDIA_DIR . "_core/warning_48.png\");'><h3 style='margin:0;'>%s:</h3><h2 style='margin:0;'>%s</h2> Exception thrown in %s%s</summary><h3>Trace:</h3>\n", $type, $exception->getMessage(), self::embedScript($exception->getFile(), $exception->getLine(), $arguments, false), $exceptionDocumentation); $exceptionDump = ''; if (class_exists(Ajde_Dump::class)) { if ($dumps = Ajde_Dump::getAll()) { $exceptionDump .= '<h2>Dumps</h2>'; foreach ($dumps as $source => $dump) { ob_start(); echo $source; if (class_exists(Kint::class)) { Kint::dump($dump[0]); } else { echo '<pre>'; var_dump($dump[0]); echo '</pre>'; } $exceptionDump .= ob_get_clean() . '<h2>Error message</h2>'; } } } $style = false; if (file_exists(LOCAL_ROOT . CORE_DIR . MODULE_DIR . '_core/res/css/debugger/handler.css')) { $style = file_get_contents(LOCAL_ROOT . CORE_DIR . MODULE_DIR . '_core/res/css/debugger/handler.css'); } if ($style === false) { // For shutdown() call $style = 'body {font: 13px sans-serif;} a {color: #005D9A;} a:hover {color: #9A0092;} h2 {color: #005D9A;} span > a {color: #9A0092;}'; } $style = '<style>' . $style . '</style>'; $script = '<script>document.getElementsByTagName("base")[0].href="";</script>'; if (Ajde::app()->getRequest()->isAjax()) { $collapsed = $exceptionDump . $exceptionMessage . $traceMessage; $header = ''; } else { $collapsed = '<div id="details">' . $exceptionDump . $exceptionMessage . $traceMessage . '</div>'; $header = '<header><h1><img src="' . config('app.rootUrl') . MEDIA_DIR . 'ajde-small.png">Something went wrong</h1><a href="javascript:history.go(-1);">Go back</a> <a href="#details">Show details</a></header>'; } $message = $style . $script . $header . $collapsed; break; case self::EXCEPTION_TRACE_ONLY: $message = ''; foreach (array_reverse($exception->getTrace()) as $i => $line) { $message .= $i . '. ' . (isset($line['file']) ? $line['file'] : 'unknown file') . ' on line ' . (isset($line['line']) ? $line['line'] : 'unknown line'); $message .= PHP_EOL; } break; case self::EXCEPTION_TRACE_LOG: $message = 'UNCAUGHT EXCEPTION' . PHP_EOL; $message .= "\tRequest " . $_SERVER['REQUEST_URI'] . ' triggered:' . PHP_EOL; $message .= sprintf("\t%s: %s in %s on line %s", $type, $exception->getMessage(), $exception->getFile(), $exception->getLine()); foreach (array_reverse($exception->getTrace()) as $i => $line) { $message .= PHP_EOL; $message .= "\t" . $i . '. ' . (isset($line['file']) ? $line['file'] : 'unknown file') . ' on line ' . (isset($line['line']) ? $line['line'] : 'unknown line'); } break; } return $message; }