@tekord
Веб-разработчик

Когда следует триггерить события ДО и ПОСЛЕ какого-то необратимого действия?

Пользователь инициирует необратимое действие — удаление своего аккаунта с сайта. Пользователю предлагается заполнить форму с указанием причины удаления, владельцу сайта это нужно для аналитики. В случае если пользователь правильно заполнил форму, программа создаёт транзакцию из следующих команд:

1. Удалить запись об аккаунте пользователя из БД;
2. Сохранить данные с формы о причинах удаления аккаунта в БД.

До того как транзакция выполнится триггерится событие EVENT_BEFORE_REMOVE. Подписчики на событие могут что-то изменить в исходных данных, например, добавить какие-то служебные данные к форме причины удаления аккаунта или отфильтровать данные. Так как на этом этапе ожидается изменение (фильтрация) и\или дополнение исходных данных, то вызов обработчиков события EVENT_BEFORE_REMOVE стоит обернуть в try/catch и если произойдёт что-то плохое у подписчиков, то отменяем транзакцию и показываем ошибку пользователю.

Примерный код:

try {
  $userAccount->trigger(UserAccount::EVENT_BEFORE_REMOVE);

  $userAccount->delete();
  $reasonForm->save();

  $transaction->commit();
}
catch (\Exception $e) {
   $transaction->rollback();

   throw $e;
}


Теперь вопрос №1: где следует триггерить событие EVENT_AFTER_REMOVE? Сразу после коммита транзакции, внутри блока try/catch или после этого блока, ведь основная работа уже выполнена?

На событие EVENT_AFTER_REMOVE будут подписаны логгеры и разные аналитические модули, которые будут изменять счётчик кол-ва удалённых пользователей и общее число пользователей. Очевидно, что подписчики на это событие уже никак не смогут повлиять на исход удаления аккаунта, он уже удалён, а обновление счётчиков не столь важная процедура.

Вопрос №2: стоит ли обернуть триггеринг события EVENT_AFTER_REMOVE в блок try/catch, а в catch писать ошибки в лог в тихом режиме, не показывая ошибки пользователям? Или лучше требовать от подписчиков чтобы они сами контролировали и логировали свои ошибки?

В первом случае при ошибке в одном обработчике, последовательность выполнения прерывается. Во втором случае подписчики с ошибками пропускаются и выполняются последующие, но при этом нужно требовать от подписчиков больше проверок.
  • Вопрос задан
  • 307 просмотров
Решения вопроса 1
qonand
@qonand
Software Engineer
1. Генерацию события EVENT_AFTER_REMOVE стоит разместить сразу после коммита. Если размещать генерацию после блока try/catch может возникнуть ситуация когда в процессе удаления возник какой-то эксепшен, Вы его поймали и откатили транзакцию. Т.е. удаления по факту не произошло, а событие сгенерируется - это не совсем правильно
2. Не стоит, подписчики должны сами обрабатывать ошибки
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы