Учебники

Эрланг – исключения

Обработка исключений требуется на любом языке программирования для обработки ошибок времени выполнения, чтобы можно было поддерживать нормальный поток приложения. Исключение обычно нарушает нормальный поток приложения, поэтому мы должны использовать обработку исключений в нашем приложении.

Обычно, когда в Erlang возникает исключение или ошибка, отображается следующее сообщение.

{"init terminating in do_boot", {undef,[{helloworld,start,[],[]}, 
{init,start_it,1,[]},{init,start_em,1,[]}]}}

Аварийный дамп будет записан в –

erl_crash.dump
init terminating in do_boot ()

В Эрланге есть 3 типа исключений –

  • Ошибка – вызов erlang: error (Reason) завершит выполнение в текущем процессе и включит трассировку стека последних функций, вызываемых с их аргументами, когда вы его перехватываете. Это исключения, которые вызывают ошибки времени выполнения выше.

  • Существует. Существует два вида выходов: «внутренние» и «внешние». Внутренние выходы запускаются вызовом функции exit / 1 и заставляют текущий процесс остановить его выполнение. Внешние выходы вызываются с помощью exit / 2 и связаны с несколькими процессами в параллельном аспекте Erlang.

  • Бросок – Бросок – это класс исключений, используемый в случаях, когда от программиста можно ожидать обработки. По сравнению с выходами и ошибками, они не несут никакого «сбоя этого процесса»! намерение позади них, а скорее они контролируют поток. Поскольку вы используете throw, ожидая, что программист с ними справится, обычно хорошей идеей является документировать их использование в модуле, использующем их.

Ошибка – вызов erlang: error (Reason) завершит выполнение в текущем процессе и включит трассировку стека последних функций, вызываемых с их аргументами, когда вы его перехватываете. Это исключения, которые вызывают ошибки времени выполнения выше.

Существует. Существует два вида выходов: «внутренние» и «внешние». Внутренние выходы запускаются вызовом функции exit / 1 и заставляют текущий процесс остановить его выполнение. Внешние выходы вызываются с помощью exit / 2 и связаны с несколькими процессами в параллельном аспекте Erlang.

Бросок – Бросок – это класс исключений, используемый в случаях, когда от программиста можно ожидать обработки. По сравнению с выходами и ошибками, они не несут никакого «сбоя этого процесса»! намерение позади них, а скорее они контролируют поток. Поскольку вы используете throw, ожидая, что программист с ними справится, обычно хорошей идеей является документировать их использование в модуле, использующем их.

Try … catch – это способ оценить выражение, позволяя вам обрабатывать как успешный случай, так и обнаруженные ошибки.

Общий синтаксис выражения try catch следующий.

Синтаксис

try Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 

catch 
TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

Выражение между try и of называется защищенным. Это означает, что любые исключения, возникающие в этом вызове, будут обнаружены. Шаблоны и выражения между try … of и catch ведут себя точно так же, как case … of .

Наконец, часть catch – здесь вы можете заменить TypeOfError на ошибку, throw или exit для каждого соответствующего типа, который мы видели в этой главе. Если тип не предоставлен, предполагается бросок.

Ниже приведены некоторые из ошибок и причины ошибок в Erlang –

ошибка Тип ошибки
badarg Плохой аргумент Аргумент имеет неправильный тип данных или неправильно сформирован.
badarith Неверный аргумент в арифметическом выражении.
{Badmatch, V} Оценка выражения соответствия не удалась. Значение V не соответствует.
function_clause Соответствующее предложение функции не найдено при оценке вызова функции.
{Case_clause, V} Соответствующая ветвь не найдена при оценке выражения case. Значение V не соответствует.
если да Не найдена истинная ветвь при вычислении выражения if.
{Try_clause, V} Соответствующая ветвь не найдена при оценке of-секции выражения try. Значение V не соответствует.
UNDEF Функция не может быть найдена при оценке вызова функции.
{Badfun, F} Что-то не так с забавным F
{Badarity, F} Веселье применяется к неправильному количеству аргументов. F описывает веселье и аргументы.
timeout_value Значение тайм-аута в выражении receive..after оценивается как-то иначе, чем целое число или бесконечность.
noproc Попытка связать с несуществующим процессом.

Ниже приведен пример того, как можно использовать эти исключения и как это делается.

  • Первая функция генерирует все возможные типы исключения.

  • Затем мы пишем функцию-оболочку для вызова generate_exception в выражении try … catch.

Первая функция генерирует все возможные типы исключения.

Затем мы пишем функцию-оболочку для вызова generate_exception в выражении try … catch.

пример

-module(helloworld). 
-compile(export_all). 

generate_exception(1) -> a; 
generate_exception(2) -> throw(a); 
generate_exception(3) -> exit(a); 
generate_exception(4) -> {'EXIT', a}; 
generate_exception(5) -> erlang:error(a). 

demo1() -> 
   [catcher(I) || I <- [1,2,3,4,5]]. 
catcher(N) -> 
   try generate_exception(N) of 
      Val -> {N, normal, Val} 
   catch 
      throw:X -> {N, caught, thrown, X}; 
      exit:X -> {N, caught, exited, X}; 
      error:X -> {N, caught, error, X} 
   end. 
      
demo2() -> 
   [{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]]. 
demo3() -> 
   try generate_exception(5) 
   catch 
      error:X -> 
         {X, erlang:get_stacktrace()} 
   end. 
   
lookup(N) -> 
   case(N) of 
      1 -> {'EXIT', a}; 
      2 -> exit(a) 
   end.

Если мы запустим программу как helloworld: demo (). , мы получим следующий вывод –