114 lines
2.9 KiB
PHP
114 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* Holds the exception (and error) handler.
|
|
* @package Sakura
|
|
*/
|
|
|
|
namespace Sakura;
|
|
|
|
use ErrorException;
|
|
use stdClass;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Exception handler.
|
|
* @package Sakura
|
|
* @author Julian van de Groep <me@flash.moe>
|
|
*/
|
|
class ExceptionHandler
|
|
{
|
|
/**
|
|
* Disables checking if the templating engine is available
|
|
* @var bool
|
|
*/
|
|
private static $disableTemplate = false;
|
|
|
|
/**
|
|
* Register as the error and exception handler.
|
|
*/
|
|
public static function register(): void
|
|
{
|
|
set_exception_handler([static::class, 'exception']);
|
|
set_error_handler([static::class, 'error']);
|
|
}
|
|
|
|
/**
|
|
* The entry point for set_exception_handler.
|
|
* @param Throwable $ex
|
|
*/
|
|
public static function exception(Throwable $ex): void
|
|
{
|
|
$report = config('dev.report_host');
|
|
|
|
if (strlen($report) > 0) {
|
|
self::report($ex, $report);
|
|
}
|
|
|
|
self::view($ex, $report);
|
|
}
|
|
|
|
/**
|
|
* The entry point for set_error_handler.
|
|
* @param int $severity
|
|
* @param string $message
|
|
* @param string $file
|
|
* @param int $line
|
|
* @throws ErrorException
|
|
*/
|
|
public static function error(int $severity, string $message, string $file, int $line): void
|
|
{
|
|
throw new ErrorException($message, 0, $severity, $file, $line);
|
|
}
|
|
|
|
/**
|
|
* Display an error message.
|
|
* @param Throwable $ex
|
|
* @param bool $reported
|
|
*/
|
|
private static function view(Throwable $ex, bool $reported = false): void
|
|
{
|
|
http_response_code(500);
|
|
|
|
$debug = config('dev.show_errors');
|
|
$cli = php_sapi_name() === 'cli';
|
|
|
|
if ($cli || $debug) {
|
|
if (!$cli) {
|
|
header('Content-Type: text/plain');
|
|
}
|
|
|
|
echo $ex;
|
|
} else {
|
|
if (!self::$disableTemplate && Template::available()) {
|
|
echo view('errors/500', compact('reported'));
|
|
} else {
|
|
// Disable templates permanently so we don't get stuck in an infinite loop
|
|
// if an exception is caused by the templating engine.
|
|
self::$disableTemplate = true;
|
|
echo "Something broke so badly that the error page failed to render.";
|
|
|
|
if ($reported) {
|
|
echo " The developers have been notified of the issue.";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Posts the exception as json to a remote server.
|
|
* @param Throwable $ex
|
|
* @param string $destination
|
|
*/
|
|
private static function report(Throwable $ex, string $destination): void
|
|
{
|
|
$send = new stdClass;
|
|
$send->Date = date('c');
|
|
$send->Message = $ex->getMessage();
|
|
$send->Code = $ex->getCode();
|
|
$send->File = $ex->getFile();
|
|
$send->Line = $ex->getLine();
|
|
$send->Trace = $ex->getTraceAsString();
|
|
|
|
Net::request($destination, 'POST', json_encode($send));
|
|
}
|
|
}
|