Существует три основных способа обработки исключений в последовательном Erlang:
- броска (
throw(Term)
)
- ошибок (
erlang:error(Reason)
)
- выходов (
exit(Reason)
)
Броски должны использоваться для нелокальных возвратов и некоторых типов исключений, которые вы ожидаете иметь возможность обрабатывать (возможно, потому что они происходят часто). Когда он поднимется, вы должны попытаться остановить его, прежде чем он выйдет за пределы вашего модуля. Обычный способ, которым он используется в stdlib, - бросить кортеж вида {error, Reason}
, который будет перехвачен функцией верхнего уровня в try...catch
перед возвратом кортежа пользователю. Пользователь может затем решить, что делать на основе этого возвращаемого значения.
Ошибки , с другой стороны, указывают на невосстановимые исключения. Обычно они требуют, чтобы пользователь изменил свой код. Они включают в себя ошибки времени выполнения, такие как if
или case ... of
ветви, которые не могут быть сопоставлены, функции, которые не могут совпадать или не существуют, и т. Д. Цель этой ошибки - аварийное завершение, которое не должно быть перехвачено или обработано в большинстве случаев локально для процесса (попросите, чтобы супервизор или процесс мониторинга поднял сообщение об ошибке, а затем зарегистрировал его для вас или обработал для пользователя на уровне интерфейса).
Выходы должны использоваться, когда вы конкретно хотите завершить процесс. Иногда немного неясно, когда использовать выходы или ошибки, но совет, который мне дали, состоит в том, чтобы дифференцировать намерение.
Ошибки и выходы редко должны обнаруживаться и обрабатываться последовательно (вы действительно должны быть уверены, что знаете, как все исправить!), Так как для этого существует другой процесс. Пусть это рухнет.
(подробнее: http://learnyousomeerlang.com/errors-and-exceptions)
Следующий уровень - при работе с ошибками в многопроцессорной среде. Стандартный способ сделать что-то на этом этапе - это связать процессы вместе (и / или использовать супервизоры), чтобы выбрать мертвые процессы и причину, по которой они это сделали: перезапустить их, записать сообщение, выполнить техническое обслуживание, обновить, пока система продолжает работать .
Вы получаете новую функцию исключения для нескольких процессов: exit(Pid, Reason)
. Это позволяет вам вызывать «выход» в другом процессе. В этом случае обработка ошибок должна быть сделана путем установки process_flag(trap_exit, true)
в процессе мониторинга, после чего вы можете получать сигналы выхода через стандартное выражение receive
.
Обратите внимание, что специальный вид выхода, а именно exit(Pid, kill)
, завершит процесс без какой-либо возможности его перехватить. Другие процессы, связанные с Pid
, должны получать сигнал вида {'EXIT', killed}
.
Используя деревья наблюдения, вы убедитесь, что ваши программы продолжают работать. Ранний сбой также важен, чтобы быть уверенным, что вы ничего не испортите; Чем раньше проблемный код перестает работать, тем легче его очистить.