@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. Не стоит, подписчики должны сами обрабатывать ошибки
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы