Added error handler
This commit is contained in:
parent
2b80012658
commit
d1f0e4360f
4 changed files with 205 additions and 7 deletions
191
app/Core/ErrorHandler.php
Normal file
191
app/Core/ErrorHandler.php
Normal file
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Core;
|
||||
|
||||
class ErrorHandler
|
||||
{
|
||||
/**
|
||||
* Уровень буфера вывода на котором работает обработчик
|
||||
* @var int
|
||||
*/
|
||||
protected $obLevel;
|
||||
|
||||
/**
|
||||
* Описание ошибки
|
||||
* @var array
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* Флаг отправки сообщения в лог
|
||||
* @var bool
|
||||
*/
|
||||
protected $logged = false;
|
||||
|
||||
/**
|
||||
* Список ошибок
|
||||
* @var array
|
||||
*/
|
||||
protected $type = [
|
||||
0 => 'OTHER_ERROR',
|
||||
\E_ERROR => 'E_ERROR',
|
||||
\E_WARNING => 'E_WARNING',
|
||||
\E_PARSE => 'E_PARSE',
|
||||
\E_NOTICE => 'E_NOTICE',
|
||||
\E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
\E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
\E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
\E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
\E_USER_ERROR => 'E_USER_ERROR',
|
||||
\E_USER_WARNING => 'E_USER_WARNING',
|
||||
\E_USER_NOTICE => 'E_USER_NOTICE',
|
||||
\E_STRICT => 'E_STRICT',
|
||||
\E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
|
||||
\E_DEPRECATED => 'E_DEPRECATED',
|
||||
\E_USER_DEPRECATED => 'E_USER_DEPRECATED',
|
||||
];
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
\set_error_handler([$this, 'errorHandler']);
|
||||
\set_exception_handler([$this, 'exceptionHandler']);
|
||||
\register_shutdown_function([$this, 'shutdownHandler']);
|
||||
|
||||
\ob_start();
|
||||
$this->obLevel = \ob_get_level();
|
||||
}
|
||||
|
||||
/**
|
||||
* Деструктор
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
\restore_error_handler();
|
||||
\restore_exception_handler();
|
||||
|
||||
//????
|
||||
}
|
||||
|
||||
/**
|
||||
* Обрабатыет перехватываемые ошибки
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $message
|
||||
* @param string $file
|
||||
* @param string $line
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function errorHandler($type, $message, $file, $line)
|
||||
{
|
||||
$error = [
|
||||
'type' => $type,
|
||||
'message' => $message,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
];
|
||||
$this->log($error);
|
||||
|
||||
if ($type & \error_reporting()) {
|
||||
$this->error = $error;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$this->logged = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обрабатывает не перехваченные исключения
|
||||
*
|
||||
* @param Exception|Throwable $e
|
||||
*/
|
||||
public function exceptionHandler($e)
|
||||
{
|
||||
$this->error = [
|
||||
'type' => 0, //????
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Окончательно обрабатывает ошибки (в том числе фатальные) и исключения
|
||||
*/
|
||||
public function shutdownHandler()
|
||||
{
|
||||
if (isset($this->error['type'])) {
|
||||
$show = true;
|
||||
} else {
|
||||
$show = false;
|
||||
$this->error = \error_get_last();
|
||||
|
||||
if (isset($this->error['type'])) {
|
||||
switch ($this->error['type']) {
|
||||
case \E_ERROR:
|
||||
case \E_PARSE:
|
||||
case \E_CORE_ERROR:
|
||||
case \E_CORE_WARNING:
|
||||
case \E_COMPILE_ERROR:
|
||||
case \E_COMPILE_WARNING:
|
||||
$show = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->error['type']) && ! $this->logged) {
|
||||
$this->log($this->error);
|
||||
}
|
||||
|
||||
while (\ob_get_level() > $this->obLevel) {
|
||||
\ob_end_clean();
|
||||
}
|
||||
if (\ob_get_level() === $this->obLevel) {
|
||||
if ($show) {
|
||||
\ob_end_clean();
|
||||
|
||||
$this->show($this->error);
|
||||
} else {
|
||||
\ob_end_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправляет сообщение в лог
|
||||
*
|
||||
* @param array $error
|
||||
*/
|
||||
protected function log(array $error)
|
||||
{
|
||||
$this->logged = true;
|
||||
$type = isset($this->type[$error['type']]) ? $this->type[$error['type']] : $this->type[0];
|
||||
$message = "PHP {$type}: \"{$error['message']}\" in {$error['file']}:[{$error['line']}]";
|
||||
$message = \preg_replace('%[\x00-\x1F]%', ' ', $message);
|
||||
|
||||
\error_log($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выводит сообщение об ошибке
|
||||
*
|
||||
* @param array $error
|
||||
*/
|
||||
protected function show(array $error)
|
||||
{
|
||||
\header('HTTP/1.1 500 Internal Server Error');
|
||||
|
||||
if (1 == \ini_get('display_errors')) {
|
||||
$type = isset($this->type[$error['type']]) ? $this->type[$error['type']] : $this->type[0];
|
||||
|
||||
echo "PHP {$type}: \"{$error['message']}\" in {$error['file']}:[{$error['line']}]";
|
||||
} else {
|
||||
echo 'Oops';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,16 +3,12 @@
|
|||
namespace ForkBB;
|
||||
|
||||
use ForkBB\Core\Container;
|
||||
use ForkBB\Core\ErrorHandler;
|
||||
use ForkBB\Models\Page;
|
||||
use RuntimeException;
|
||||
|
||||
// боевой
|
||||
#\error_reporting(E_ALL);
|
||||
#\ini_set('display_errors', 0);
|
||||
#\ini_set('log_errors', 1);
|
||||
// разраб
|
||||
\error_reporting(E_ALL);
|
||||
\ini_set('display_errors', 1);
|
||||
\error_reporting(\E_ALL ^ \E_NOTICE);
|
||||
\ini_set('display_errors', 0);
|
||||
\ini_set('log_errors', 1);
|
||||
|
||||
\mb_language('uni');
|
||||
|
@ -21,6 +17,8 @@ use RuntimeException;
|
|||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$errorHandler = new ErrorHandler();
|
||||
|
||||
if (\is_file(__DIR__ . '/config/main.php')) {
|
||||
$c = new Container(include __DIR__ . '/config/main.php');
|
||||
} elseif (\is_file(__DIR__ . '/config/install.php')) {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?php
|
||||
|
||||
\error_reporting(\E_ALL);
|
||||
\ini_set('display_errors', 1);
|
||||
\ini_set('log_errors', 1);
|
||||
|
||||
return [
|
||||
'BASE_URL' => 'http://forkbb.local',
|
||||
'DEBUG' => 0,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?php
|
||||
|
||||
# development
|
||||
#\error_reporting(\E_ALL);
|
||||
#\ini_set('display_errors', 1);
|
||||
#\ini_set('log_errors', 1);
|
||||
|
||||
return [
|
||||
'BASE_URL' => '_BASE_URL_',
|
||||
'EOL' => PHP_EOL, // Define line breaks in mail headers; possible values can be PHP_EOL, "\r\n", "\n" or "\r"
|
||||
|
|
Loading…
Add table
Reference in a new issue