This commit is contained in:
2026-01-01 21:10:46 +08:00
parent 5c1b19c08a
commit 6c31ffa120
26 changed files with 1171 additions and 209 deletions

View File

@@ -0,0 +1,97 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Psr\Http\Message\{
ResponseInterface,
ServerRequestInterface};
use Psr\Log\LoggerInterface;
use Slim\Handlers\ErrorHandler as SlimErrorHandler;
use Throwable;
/**
* Обработчик ошибок
*/
class ExceptionHandler extends SlimErrorHandler
{
/**
* Логирует ошибку и отдаёт JSON-ответ с необходимым содержимым
*
* @param ServerRequestInterface $request
* @param Throwable $exception
* @param bool $displayErrorDetails
* @param bool $logErrors
* @param bool $logErrorDetails
* @param LoggerInterface|null $logger
* @return ResponseInterface
*/
public function __invoke(
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
): ResponseInterface {
$payload = $this->payload($exception, $displayErrorDetails);
$response = app()->getResponseFactory()->createResponse();
$response->getBody()->write(json_encode($payload, JSON_UNESCAPED_UNICODE));
return $response;
}
/**
* Возвращает структуру исключения для контекста
*
* @param Throwable $e Исключение
* @param bool $logErrorDetails Признак дополнения деталями
* @return array
*/
protected function context(Throwable $e, bool $logErrorDetails): array
{
$result = ['code' => $e->getCode()];
$logErrorDetails && $result += [
'class' => $e::class,
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace()
];
return $result;
}
/**
* Возвращает структуру исключения для передачи в ответе
*
* @param Throwable $e Исключение
* @param bool $displayErrorDetails Признак дополнения деталями
* @return array
*/
protected function payload(Throwable $e, bool $displayErrorDetails): array
{
$result = [
'error' => [
'code' => $e->getCode(),
'message' => $e->getMessage(),
],
];
$displayErrorDetails && $result['error'] += [
'class' => $e::class,
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace(),
];
return $result;
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Exception;
class FileNotFoundException extends Exception
{
public function __construct(string $filepath)
{
parent::__construct('Файл не найден: ' . $filepath);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Exception;
class FileReadException extends Exception
{
public function __construct(string $filepath)
{
parent::__construct('Ошибка чтения файла: ' . $filepath);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Exception;
class IniParsingException extends Exception
{
public function __construct(string $filepath)
{
parent::__construct('Ошибка разбора файла: ' . $filepath);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Exception;
class InvalidTelegramSecretException extends Exception
{
public function __construct()
{
parent::__construct("Ошибка валидации запроса от Telegram Bot API");
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use Exception;
class PlaylistNotFoundException extends Exception
{
public function __construct(string $code)
{
parent::__construct("Плейлист '{$code}' не найден");
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* Copyright (c) 2025, Антон Аксенов
* This file is part of m3u.su project
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
*/
declare(strict_types=1);
namespace App\Exceptions;
use InvalidArgumentException;
class PlaylistWithoutUrlException extends InvalidArgumentException
{
public function __construct(string $code)
{
parent::__construct("Плейлист '{$code}' имеет неверный url");
}
}