Improve error handling and add detailed debugging option

This commit is contained in:
Dale Davies
2023-04-11 22:47:02 +01:00
parent d5467bf436
commit 345aced953
8 changed files with 171 additions and 9 deletions

View File

@@ -90,6 +90,7 @@ class Config {
$this->config->set($key, $value);
}
}
/**
* Determine if any configuration params are missing in the list loaded
* from the config.php.
@@ -121,6 +122,15 @@ class Config {
return trim($this->config->get($key));
}
/**
* Get all config paramaters and values as an array.
*
* @return array Multidimensional array of config params.
*/
public function get_all(): array {
return $this->config->toArray();
}
/**
* Attempt to converts a string to a boolean correctly, will return the parsed boolean
* or null on failure.

View File

@@ -0,0 +1,66 @@
<?php
/**
* ██ ██ ██ ███ ███ ██████
* ██ ██ ██ ████ ████ ██ ██
* ██ ██ ██ ██ ████ ██ ██████
* ██ ██ ██ ██ ██ ██ ██ ██
* █████ ██████ ██ ██ ██
*
* @author Dale Davies <dale@daledavies.co.uk>
* @copyright Copyright (c) 2023, Dale Davies
* @license MIT
*/
namespace Jump\Debugger;
class ErrorLogger implements \Tracy\ILogger {
public function log($message, $priority = self::INFO): void {
$logmessage = $this->format_message($message) . PHP_EOL;
$logmessage .= $this->format_backtrace($message->getTrace(), true) . PHP_EOL;
error_log($logmessage);
}
public static function format_message($message): string {
if ($message instanceof \Throwable) {
foreach (\Tracy\Helpers::getExceptionChain($message) as $exception) {
$tmp[] = ($exception instanceof \ErrorException
? \Tracy\Helpers::errorTypeToString($exception->getSeverity()) . ': ' . $exception->getMessage()
: get_debug_type($exception) . ': ' . $exception->getMessage() . ($exception->getCode() ? ' #' . $exception->getCode() : '')
);
}
$message = implode("\ncaused by ", $tmp);
} elseif (!is_string($message)) {
$message = \Tracy\Dumper::toText($message);
}
return trim($message);
}
public function format_backtrace($callers) {
if (empty($callers)) {
return '';
}
$from = '';
foreach ($callers as $caller) {
if (!isset($caller['line'])) {
$caller['line'] = '?'; // probably call_user_func()
}
if (!isset($caller['file'])) {
$caller['file'] = 'unknownfile'; // probably call_user_func()
}
$from .= '* ';
$from .= 'line ' . $caller['line'] . ' of ' . str_replace(dirname(__DIR__), '', $caller['file']);
if (isset($caller['function'])) {
$from .= ': call to ';
if (isset($caller['class'])) {
$from .= $caller['class'] . $caller['type'];
}
$from .= $caller['function'] . '()';
} else if (isset($caller['exception'])) {
$from .= ': '.$caller['exception'].' thrown';
}
$from .= PHP_EOL;
}
$from .= '';
return $from;
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* ██ ██ ██ ███ ███ ██████
* ██ ██ ██ ████ ████ ██ ██
* ██ ██ ██ ██ ████ ██ ██████
* ██ ██ ██ ██ ██ ██ ██ ██
* █████ ██████ ██ ██ ██
*
* @author Dale Davies <dale@daledavies.co.uk>
* @copyright Copyright (c) 2023, Dale Davies
* @license MIT
*/
namespace Jump\Debugger;
class JumpConfigPanel {
public static function panel(?\Throwable $e) {
if ($e === null) {
$content = '<pre>';
foreach ((new \Jump\Config())->get_all() as $param => $value) {
$content .= '<b>'.$param.'</b> : '.$value.'<br>';
}
$content .= '</pre>';
return [
'tab' => 'Jump Config',
'panel' => $content,
'bottom' => true
];
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* ██ ██ ██ ███ ███ ██████
* ██ ██ ██ ████ ████ ██ ██
* ██ ██ ██ ██ ████ ██ ██████
* ██ ██ ██ ██ ██ ██ ██ ██
* █████ ██████ ██ ██ ██
*
* @author Dale Davies <dale@daledavies.co.uk>
* @copyright Copyright (c) 2023, Dale Davies
* @license MIT
*/
namespace Jump\Debugger;
class JumpVersionPanel {
public static function panel(?\Throwable $e) {
if ($e === null) {
$version = file_get_contents(__DIR__ . '/../../.jump-version');
return [
'tab' => 'Jump Version',
'panel' => '<pre>'.$version.'</pre>',
'bottom' => true
];
}
return null;
}
}

View File

@@ -26,16 +26,28 @@ class Main {
private \Nette\Http\Session $session;
public function __construct() {
// We can't do anything without the config object.
// Some initial configuration of Tracy for logging/debugging.
Debugger::$errorTemplate = __DIR__ . '/../templates/errorpage.php';
Debugger::setLogger(new \Jump\Debugger\ErrorLogger);
Debugger::getBlueScreen()->addPanel(
[\Jump\Debugger\JumpVersionPanel::class, 'panel']
);
Debugger::getBlueScreen()->addPanel(
[\Jump\Debugger\JumpConfigPanel::class, 'panel']
);
$debugmode = Debugger::Development;
// We can't do much without the config object so get that next.
$this->config = new Config();
// Set something to either display detailed debugging info or handle exceptions
// as early as possible during initialisation.
if ($this->config->get('debug')) {
Debugger::enable(Debugger::Development);
} else {
set_exception_handler([$this, 'exception_handler']);
// Now we have config, enable detailed debugging info as early as possible
// during initialisation
if (!$this->config->get('debug')) {
$debugmode = Debugger::Production;
}
// Tell Tracy to handle errors and exceptions.
Debugger::enable($debugmode);
// Carry on setting things up.
$this->cache = new Cache($this->config);

View File

@@ -24,7 +24,6 @@ class ErrorPage {
'message' => $message,
'wwwurl' => $config->get_wwwurl(),
]);
http_response_code($httpcode);
die($content);
}
}

View File

@@ -9,7 +9,7 @@
</head>
<body class="errorpage">
<div class="content fixed">
<div class="greeting">{{code}}</div>
<div class="greeting">Error ({{code}})</div>
{{message}}
</div>
<div class="background fixed"></div>

View File

@@ -0,0 +1,15 @@
<?php
/**
* ██ ██ ██ ███ ███ ██████
* ██ ██ ██ ████ ████ ██ ██
* ██ ██ ██ ██ ████ ██ ██████
* ██ ██ ██ ██ ██ ██ ██ ██
* █████ ██████ ██ ██ ██
*
* @author Dale Davies <dale@daledavies.co.uk>
* @copyright Copyright (c) 2023, Dale Davies
* @license MIT
*/
$config = new Jump\Config();
\Jump\Pages\ErrorPage::display($config, 500, 'Something went wrong, please use debug option to see details.');