-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
98dabcb
commit 88281fa
Showing
13 changed files
with
1,366 additions
and
922 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,37 @@ | ||
# Introduction | ||
|
||
**BaseException** - библиотека унификации исключений для *PHP*. | ||
|
||
**BaseException** решает задачи: | ||
|
||
1. Метаданные исключений. | ||
2. Шаблонизация сообщений. | ||
2. Аспектирование исключений. | ||
3. Нормализация исключений при помощи "контейнеров". | ||
4. Регистрация исключений в глобальном реестре. | ||
|
||
## Метаданные исключений и шаблонизация | ||
|
||
При анализе исключений важно иметь ясное представление о том, что произошло. | ||
Для этого необходимо хранить метаданные исключения, которые помогут в дальнейшем анализе. | ||
Данная библиотека реализует возможность создавать исключения с контекстом, который содержит метаданные исключения. | ||
|
||
Метаданные исключения представляют собой ассоциативный массив, | ||
элементами которого могут быть только простые типы данных. | ||
|
||
## Поддержка шаблонов сообщений | ||
|
||
**BaseException** поддерживает концепцию *шаблона сообщения* (начиная с версии 2.0). | ||
Шаблон сообщения - это строка, содержащая *placeholders*, | ||
которые заменяются на значения данных из контекста исключения. | ||
Формат шаблона соответствует [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). | ||
|
||
Когда исключение создаётся, в конструктор передаются данные, | ||
которые будут использоваться для замены *placeholders* в шаблоне сообщения. | ||
Конструктор использует шаблон и генерирует описание исключения по шаблону и метаданным. | ||
|
||
Шаблон исключения позволяет добиться нескольких важных бенефитов: | ||
* Возможность перевода сообщений об ошибках на разные языки, основываясь на шаблоне. | ||
* Возможность группировать исключения по шаблону. | ||
|
||
Шаблонизация сообщений позволяет записать в журнал не только результирующее сообщение, | ||
но и данные, которые были использованы для его формирования: | ||
|
||
```php | ||
$exception = new BaseException(['template' => 'User {user} from {ip} is not allowed', 'user' => $user, 'ip' => $ip]); | ||
$logger->error($exception); | ||
``` | ||
|
||
Это даёт возможность в дальнейшем анализировать журнал и понимать, | ||
какие данные были использованы для формирования сообщения об ошибке, | ||
группировать исключения по шаблону, либо делать поиск по метаданным. | ||
|
||
## Аспектирование исключений | ||
|
||
Аспект - это класс характеристик исключения, который позволяет обобщать код и задачи по обработке исключений. | ||
Например, аспекты позволяют ответить на вопросы: | ||
|
||
- кто виноват: программист или система; | ||
- что делать: игнорировать проблему или немедленно решать. | ||
|
||
## Нормализация исключений | ||
|
||
Нормализация исключений - это поддержка системой ограниченного числа выброшенных исключений. | ||
Она может достигаться такими способами: | ||
|
||
1. Наследование. | ||
2. Привидение к контейнеру. | ||
3. Интерфейсы. | ||
|
||
Например, привидение к контейнеру: | ||
|
||
```php | ||
try | ||
{ | ||
... | ||
} | ||
catch(\Exception $e) | ||
{ | ||
// BaseException наследует характеристики $e | ||
throw new BaseException($e); | ||
} | ||
``` | ||
|
||
## Регистрация исключений | ||
|
||
**BaseException** позволяет регистрировать исключения в глобальном реестре до того, как исключение, будет выброшено. | ||
На текущий момент эта возможность существует, но не используется на практике. | ||
Тем не менее в некоторых ситуациях, она может стать дополнительным инструментом для анализа исключений. | ||
|
||
## Небольшая библиотека готовых исключений | ||
|
||
Кроме реализации сервисного кода, **BaseException** так же содержит небольшой список готовых классов для создания типичных исключений. | ||
|
||
# Introduction | ||
|
||
**BaseException** is a library for exception unification in *PHP*. | ||
|
||
**BaseException** addresses the following tasks: | ||
|
||
1. Exception metadata. | ||
2. Message templating. | ||
3. Exception aspectization. | ||
4. Exception normalization using "containers." | ||
5. Exception registration in a global registry. | ||
|
||
## Exception Metadata and Templating | ||
|
||
When analyzing exceptions, it is important to have a clear understanding of what happened. For this, it is necessary to store exception metadata to assist in further analysis. This library enables the creation of exceptions with context that includes exception metadata. | ||
|
||
Exception metadata is an associative array containing only simple data types. | ||
|
||
## Support for Message Templates | ||
|
||
**BaseException** supports the concept of *message templates* (starting from version 2.0). A message template is a string containing *placeholders*, which are replaced with context data values. The template format complies with [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). | ||
|
||
When an exception is created, data is passed to the constructor to replace *placeholders* in the message template. The constructor uses the template and generates a description of the exception based on the template and metadata. | ||
|
||
The exception template provides several important benefits: | ||
- Ability to translate error messages into different languages based on the template. | ||
- Ability to group exceptions by template. | ||
|
||
Message templating allows logging not only the resulting message but also the data used to form it: | ||
|
||
```php | ||
$exception = new BaseException(['template' => 'User {user} from {ip} is not allowed', 'user' => $user, 'ip' => $ip]); | ||
$logger->error($exception); | ||
``` | ||
|
||
This makes it possible to analyze the log later and understand what data was used to form the error message. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,59 @@ | ||
# Paradigm | ||
|
||
## Исключения и логирование | ||
|
||
Создание классов исключений тесно связаны с методикой логирования. | ||
|
||
Исключения создаются с двумя целями: | ||
|
||
1. Передать информацию о произошедшей ошибке для кода. | ||
2. Предоставить достаточную информацию для логирования. | ||
|
||
Для решения первой задачи, используются классы и интерфейсы, позволяя коду по типу исключения определить, что произошло. | ||
Для решения второй задачи, используются метаданные исключения, которые позволяют логировать исключения с дополнительной информацией. | ||
|
||
Поэтому, создавая новый класс исключения, необходимо учитывать, | ||
что он должен содержать метаданные, которые будут использоваться для логирования. | ||
|
||
```php | ||
|
||
final class UserNotAllowed extends \IfCastle\Exceptions\BaseException | ||
{ | ||
protected string $template = 'User {user} from {ip} is not allowed'; | ||
protected array $tags = ['user', 'auth']; | ||
|
||
public function __construct(string $user, string $ip) | ||
{ | ||
parent::__construct([ | ||
'user' => $user, | ||
'ip' => $ip | ||
]); | ||
} | ||
|
||
``` | ||
|
||
В данном примере, класс `UserNotAllowed` содержит шаблон сообщения и теги, которые будут использоваться для логирования. | ||
Когда это исключение попадёт в логгер, он сможет использовать шаблон сообщения и теги для формирования сообщения об ошибке. | ||
|
||
```php | ||
$exception = new UserNotAllowed('admin', '127.0.0.1'); | ||
$logger->error($exception); | ||
``` | ||
|
||
Если в качестве системы логирования вы используете OpenTelemetry, | ||
в таком случае метаданные исключения будут использоваться для формирования атрибутов, | ||
которые попадут в трейсер вместе с тегами и шаблоном сообщения. | ||
|
||
## Исключения и теги | ||
|
||
Теги позволяют сгруппировать исключения произвольным образом. | ||
|
||
Создавая класс исключения можно определить теги, которые позже попадут в логгер. | ||
|
||
```php | ||
final class MyException extends \IfCastle\Exceptions\BaseException | ||
{ | ||
protected array $tags = ['system', 'service']; | ||
} | ||
``` | ||
|
||
Вы так же можете передать теги в конструкторе исключения. | ||
|
||
```php | ||
$exception = new MyException(['tags' => ['custom', 'tag']]); | ||
$logger->error($exception); | ||
``` | ||
|
||
Теги, добавленные в конструкторе, будут объединены с тегами, определёнными в классе исключения. | ||
|
||
## Исключения и аспекты | ||
|
||
Иногда нужно разделить разные исключения по особым типам обработки. | ||
Например, некоторые исключения могут быть показаны пользователю, в то время, когда другие -- нет. | ||
|
||
`BaseException` предлагает для этого специальный интерфейс: `ClientAvailableInterface`, | ||
который указывает, что исключение может быть показано пользователю. | ||
|
||
Интерфейс так же содержит дополнительные методы: | ||
* `getClientMessage` | ||
* `clientSerialize` | ||
|
||
Которые позволяют получить сообщение для пользователя и сериализовать исключение для клиента особым образом, | ||
в то время как в журнал будут записаны метаданные исключения. | ||
|
||
Кроме аспекта `ClientAvailableInterface`, `BaseException` так же предлагает такие аспекты: | ||
* `SystemExceptionInterface` - исключение, которое произошло из-за ошибки в системе, например диск переполнен. | ||
* `RuntimeExceptionInterface` - исключение, которое случилось во время работы программы, но не является ошибкой программиста. | ||
|
||
Все другие исключения считаются ошибками программиста и не должны быть показаны пользователю. | ||
|
||
# Paradigm | ||
|
||
## Exceptions and Logging | ||
|
||
Creating exception classes is closely related to the logging methodology. | ||
|
||
Exceptions are created with two goals: | ||
|
||
1. To convey information about the error to the code. | ||
2. To provide sufficient information for logging. | ||
|
||
To accomplish the first task, classes and interfaces are used, allowing the code to determine the error type. To achieve the second goal, exception metadata is used, allowing exceptions to be logged with additional information. | ||
|
||
Therefore, when creating a new exception class, it is essential to consider that it should contain metadata used for logging. | ||
|
||
```php | ||
final class UserNotAllowed extends \IfCastle\Exceptions\BaseException | ||
{ | ||
protected string $template = 'User {user} from {ip} is not allowed'; | ||
protected array $tags = ['user', 'auth']; | ||
|
||
public function __construct(string $user, string $ip) | ||
{ | ||
parent::__construct([ | ||
'user' => $user, | ||
'ip' => $ip | ||
]); | ||
} | ||
} | ||
``` | ||
|
||
In this example, the `UserNotAllowed` class contains a message template and tags used for logging. When this exception is logged, the logger can use the message template and tags to form an error message. | ||
|
||
```php | ||
$exception = new UserNotAllowed('admin', '127.0.0.1'); | ||
$logger->error($exception); | ||
``` | ||
|
||
If you use OpenTelemetry as your logging system, the exception metadata will be used to form attributes that will be included in the tracer along with tags and the message template. | ||
|
||
## Exceptions and Tags | ||
|
||
Tags allow grouping exceptions in an arbitrary manner. | ||
|
||
When creating an exception class, you can define tags that will later be included in the logger. | ||
|
||
```php | ||
final class MyException extends \IfCastle\Exceptions\BaseException | ||
{ | ||
protected array $tags = ['system', 'service']; | ||
} | ||
``` | ||
|
||
You can also pass tags in the exception constructor. | ||
|
||
```php | ||
$exception = new MyException(); | ||
``` |
Oops, something went wrong.