Дружественные исключения
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Дружественные исключения
Идея "дружественного исключения" в том, что можно реализовать интерфейс FriendlyExceptionInterface(https://github.com/yiisoft/friendlyexce ... erface.php) и предоставить для исключения описание того, как решить возникшую проблему. Обработчик ошибок, соответственно, может эту информацию показывать на экране ошибки вместе с обычными трейсами.
Изначально интерфейс был частью пакета yii-web, в котором уже есть обработчик, способный отображать дополнительную информацию, но, подумаю пару дней, я понял что интерфейс полезен для консольных приложений и использования вне Yii.
Итак, самый маленький пакет Yii 3:
https://github.com/yiisoft/friendlyexception
Что думаете?
Изначально интерфейс был частью пакета yii-web, в котором уже есть обработчик, способный отображать дополнительную информацию, но, подумаю пару дней, я понял что интерфейс полезен для консольных приложений и использования вне Yii.
Итак, самый маленький пакет Yii 3:
https://github.com/yiisoft/friendlyexception
Что думаете?
Нравится Yii? Давайте сделаем его лучше!.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Дружественные исключения
А какие мысли вы ожидаете? Сделать ревью кода?
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Дружественные исключения
1. Втащили бы себе в проект?
2. Достаточно ли такого интерфейса?
2. Достаточно ли такого интерфейса?
Нравится Yii? Давайте сделаем его лучше!.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Дружественные исключения
И? Где вы здесь хотите использовать getSolution? По факту это часть getMessage, которую можно выводить отдельно. Остальное все равно реализовывается отдельно в частных исключениях.
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Дружественные исключения
Не понял вопроса. Я не хочу использовать в исключении getSolution(), я его реализую в нём. getSuggestedAlternatives() в этом случае это как раз и есть getSolution().
Если отдельно, то не часть getMessage(). Например, getMessage() пишется в лог, а getSolution() уж точно в логе не место.По факту это часть getMessage, которую можно выводить отдельно.
Вот это совсем не понял Что остальное и в каких исключениях?Остальное все равно реализовывается отдельно в частных исключениях.
Нравится Yii? Давайте сделаем его лучше!.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Дружественные исключения
Именно об этом я и говорю, getSolution() должен быть универсальным, а значит должен работать с контекстом. Потому что getSuggestedAlternatives() работает с контекстом (команда/роут). Значит нам нужен контекст в исключении и желательно чтобы он был доступен в обработчике. Например так.
Код: Выделить всё
interface FriendlyExceptionInterface
{
public function getName(): string;
public function getSolution(): ?string;
public function getContext(): ?string;
}
Код: Выделить всё
class ErrorException extends \ErrorException implements FriendlyExceptionInterface
{
//...
private $context;
public function __construct($message = '', $context = null, $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, \Exception $previous = null)
{
parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
$this->context = $context;
$this->addXDebugTraceToFatalIfAvailable();
}
public function getContext(): ?string
{
return $this->context;
}
//....
Код: Выделить всё
lass UnknownCommandException extends ErrorException
{
//....
public function getSolution(): ?string
{
return $this->getSuggestedAlternatives();
}
protected function getSuggestedAlternatives()
{
//working with $this->context instead of $this->command
//...
}
}
Код: Выделить всё
try {
//execute commands
} catch (\ErrorExeption $e) {
$message = $e->getMessage();
if ($e instanceof FriendlyExceptionInterface) {
$name = $e->getName();
$solution = $e->getSolution();
$context = $e->getContext();
$message = "{$name}:{$message}\n{$solution}";
//use a custom solution
if (($e instanceof UnknownCommandException) && empty($solution)) {
$message .= "\n Command {$context} - ...custom solution...";
}
//custom action
if (($e instanceof BadPasswordException) && $context == 'account/send-money' ){
sendEmailToSecurity('Danger! Unauthorized money transfer has been detected!');
}
}
}
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Дружественные исключения
Контекст именно для этого интерфейса не важен. Интерфейс не про то, как мы будем собирать вывод, а про то, что мы будем выводить. Выводим мы сообщение, трейс и подсказку-решение. Если для их формирования в конкретном исключении необходимо название текущей команды, то требуем его в конструкторе этого исключения:
Код: Выделить всё
class UnknownCommandException extends ErrorException
{
private $command;
public function __construct(string $command)
{
$this->command = $command;
parent::__construct('Unknown command '. $command);
}
public function getSolution(): ?string
{
$alternatives = $this->getSuggestedAlternatives();
if ($alternatives === []) {
return null;
}
return 'Did you mean one of"' . implode('", "', $alternatives) . '"?';
}
protected function getSuggestedAlternatives(): array
{
// working with $this->command
// ...
}
}
Нравится Yii? Давайте сделаем его лучше!.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Дружественные исключения
Ок, пусть будет так. А почему бы не вынести в независимый пакет https://github.com/yiisoft/yii-web/tree ... rorHandler целиком? Там вроде только одна зависимость фреймворка Yiisoft\Yii\Web\Info и этот момент решаем.samdark писал(а): ↑2019.09.21, 19:07 Контекст именно для этого интерфейса не важен. Интерфейс не про то, как мы будем собирать вывод, а про то, что мы будем выводить. Выводим мы сообщение, трейс и подсказку-решение. Если для их формирования в конкретном исключении необходимо название текущей команды, то требуем его в конструкторе этого исключения:
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Дружественные исключения
Можно и вынести, конечно. Вы первый кто спросил.
Нравится Yii? Давайте сделаем его лучше!.