From cd22f8def50ede21e2a8b333664cf332aa130c63 Mon Sep 17 00:00:00 2001 From: slawkens <slawkens@gmail.com> Date: Fri, 2 Jun 2023 15:20:07 +0200 Subject: [PATCH] Use Whoops only if installed, otherwise use myaac exception handler --- composer.json | 4 +- system/exception.php | 66 ++++++++++++++++++++--- system/libs/SensitiveException.php | 3 ++ system/templates/exception.html.twig | 79 ++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 system/libs/SensitiveException.php create mode 100644 system/templates/exception.html.twig diff --git a/composer.json b/composer.json index 0a17947e..b1300e34 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,9 @@ "twig/twig": "^2.0", "erusev/parsedown": "^1.7", "nikic/fast-route": "^1.3", - "matomo/device-detector": "^6.0", + "matomo/device-detector": "^6.0" + }, + "require-dev": { "filp/whoops": "^2.15" } } diff --git a/system/exception.php b/system/exception.php index 9a233000..077d0f3f 100644 --- a/system/exception.php +++ b/system/exception.php @@ -1,6 +1,6 @@ <?php /** - * Whoops exception handler + * Exception handler * * @package MyAAC * @author Slawkens <slawkens@gmail.com> @@ -8,13 +8,63 @@ * @link https://my-aac.org */ -$whoops = new \Whoops\Run; +if (class_exists(\Whoops\Run::class)) { + $whoops = new \Whoops\Run; + if(IS_CLI) { + $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); + } + else { + $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + } -if(IS_CLI) { - $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); -} -else { - $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + $whoops->register(); + return; } -$whoops->register(); +require LIBS . 'SensitiveException.php'; + +/** + * @param Exception $exception + */ +function exception_handler($exception) { + $message = $exception->getMessage(); + if($exception instanceof SensitiveException) { + $message = 'This error is sensitive and has been logged into ' . LOGS . 'error.log.<br/>View this file for more information.'; + + // log error to file + $f = fopen(LOGS . 'error.log', 'ab'); + if(!$f) { + $message = 'We wanted to save detailed informations about this error, but file: ' . LOGS . "error.log couldn't be opened for writing.. so the detailed information couldn't be saved.. are you sure directory system/logs is writable by web server? Correct this, and then refresh this site."; + } + else { + fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $exception->getMessage() . PHP_EOL); + fclose($f); + } + } + + $backtrace_formatted = nl2br($exception->getTraceAsString()); + + $message = $message . "<br/><br/>File: {$exception->getFile()}<br/>Line: {$exception->getLine()}"; + + // display basic error message without template + // template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right + $template_file = SYSTEM . 'templates/exception.html.twig'; + if(!file_exists($template_file)) { + echo 'Something went terribly wrong..<br/><br/>'; + echo "$message<br/><br/>"; + echo 'Backtrace:<br>'; + echo $backtrace_formatted; + return; + } + + // display beautiful error message + // the file is .twig.html, but its not really parsed by Twig + // we just replace some values manually + // cause in case Twig throws exception, we can show it too + $content = file_get_contents($template_file); + $content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); + + echo $content; +} + +set_exception_handler('exception_handler'); diff --git a/system/libs/SensitiveException.php b/system/libs/SensitiveException.php new file mode 100644 index 00000000..58978198 --- /dev/null +++ b/system/libs/SensitiveException.php @@ -0,0 +1,3 @@ +<?php + +class SensitiveException extends Exception {} diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig new file mode 100644 index 00000000..7a31b4bb --- /dev/null +++ b/system/templates/exception.html.twig @@ -0,0 +1,79 @@ +<!doctype html> + +<html lang="en"> +<head> + <meta charset="utf-8"> + + <title>Something went wrong...</title> + <meta name="description" content="myaac"> + <meta name="generator" content="MyAAC"> + + <link rel="stylesheet" href="tools/css/messages.css"> + <link rel="shortcut icon" href="images/error.ico"> + <base href="{{ BASE_URL }}" /> + + <style> + body{ + background-color: #e3e7ed; + font-family: Verdana, Geneva, sans-serif; + } + .center { + height: 500px; + position: absolute; + top:0; + bottom: 0; + left: 0; + right: 0; + + margin: auto; + } + + .wide{ + min-width: 350px; + max-width: 350px; + } + + .big{ + font-size: 20px!important; + } + + #footer { + position: absolute; + bottom: 15px; + width: 100%; + + border-top: 1px solid #eee; + text-align: center; + color: #555; + } + + #footer p { + text-align: center; + } + + .error { + font-weight: normal; + font-size: 12px; + } + </style> + <!--[if lt IE 9]> + <script src="tools/js/html5shiv.min.js"></script> + <![endif]--> +</head> +<body> + <div class="center wide"> + <h2 class="wide">Whoops something went wrong...</h2> + <div class="error wide"> + Exception class: {{ exceptionClass }}() + <br/><br/> + {{ message }} + <br/><br/><br/> + <b>Backtrace:</b><br/><br/> + {{ backtrace }} + </div> + </div> + <div id="footer"> + <p>{{ powered_by }}</p> + </div> +</body> +</html>