75 lines
2.5 KiB
PHP
75 lines
2.5 KiB
PHP
<?php
|
||
/**
|
||
* @package Bicycle
|
||
* @author Egor Isaev
|
||
* @description MyException.php
|
||
* @copyright (c) 03/06/2026
|
||
*/
|
||
|
||
namespace System\Classes;
|
||
|
||
use Exception;
|
||
use Throwable;
|
||
|
||
/**
|
||
* Кастомное исключение с подстановкой переменных в сообщение (strtr).
|
||
* Зарегистрировано через set_exception_handler в Core::init().
|
||
*/
|
||
class MyException extends Exception
|
||
{
|
||
/**
|
||
* @param string $message Сообщение, может содержать плейсхолдеры для $variables
|
||
* @param array|null $variables Карта замен вида [':url' => '/foo'] для strtr
|
||
* @param int $code Код исключения
|
||
* @param Throwable|null $previous Предыдущее исключение
|
||
*/
|
||
public function __construct(string $message = "", ?array $variables = null, int $code = 0, ?Throwable $previous = null)
|
||
{
|
||
if ($variables) {
|
||
$message = strtr($message, $variables);
|
||
}
|
||
|
||
parent::__construct($message, $code, $previous);
|
||
}
|
||
|
||
/**
|
||
* Обработчик неперехваченных исключений: выводит шаблон ошибки.
|
||
* В DEVELOPMENT показывает детали, иначе — страницу 500.
|
||
*
|
||
* @param Throwable $e Перехваченное исключение
|
||
* @return void
|
||
*/
|
||
public static function handler(Throwable $e): void
|
||
{
|
||
$http_code = ($e->getCode() >= 100 && $e->getCode() <= 599) ? $e->getCode() : 500;
|
||
http_response_code($http_code);
|
||
|
||
Log::error(
|
||
sprintf(
|
||
'%s [%d]: %s в %s:%d | %s',
|
||
get_class($e), $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(),
|
||
Log::requestInfo()
|
||
)
|
||
);
|
||
|
||
if (Core::$environment >= Core::DEVELOPMENT) {
|
||
$class = get_class($e);
|
||
$code = $e->getCode();
|
||
$message = $e->getMessage();
|
||
$file_ = $e->getFile();
|
||
$line = $e->getLine();
|
||
$xdebug_message = property_exists($e, 'xdebug_message') ? $e->xdebug_message : '';
|
||
|
||
$view = Core::findFile('view/exception', 'error', 'html');
|
||
if ($view) {
|
||
include $view;
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (($view500 = Core::findFile('view/errors', '500', 'html')) !== false) {
|
||
include $view500;
|
||
}
|
||
}
|
||
}
|