Bicycle/System/Classes/MyException.php
Egor Isaev 8fdcd0b901 dev
2026-08-07 13:44:45 +03:00

80 lines
3.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @package Bicycle
* @author Egor Isaev
* @description MyException.php
* @copyright (c) 03/06/2026
*/
namespace System\Classes;
use RuntimeException;
use Throwable;
/**
* Кастомное исключение с подстановкой переменных в сообщение (strtr).
* Зарегистрировано через set_exception_handler в Core::init().
*
* extends RuntimeException (не Exception) — PhpStorm по умолчанию считает RuntimeException
* unchecked-исключением (см. "Unchecked Exceptions" в Settings | PHP | Analysis, встроенный
* дефолт платформы, без какой-либо настройки проекта) и не требует @throws MyException
* на каждом методе по всей цепочке вызовов, как для обычного Exception.
*/
class MyException extends RuntimeException
{
/**
* @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;
}
}
}