Erlang - Excepciones

Se requiere el manejo de excepciones en cualquier lenguaje de programación para manejar los errores de tiempo de ejecución de modo que se pueda mantener el flujo normal de la aplicación. La excepción normalmente interrumpe el flujo normal de la aplicación, razón por la cual necesitamos utilizar el manejo de excepciones en nuestra aplicación.

Normalmente, cuando ocurre una excepción o error en Erlang, se mostrará el siguiente mensaje.

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

El volcado de emergencia se escribirá en:

erl_crash.dump
init terminating in do_boot ()

En Erlang, hay 3 tipos de excepciones:

  • Error - llamando erlang:error(Reason)terminará la ejecución en el proceso actual e incluirá un seguimiento de la pila de las últimas funciones llamadas con sus argumentos cuando lo detecte. Este es el tipo de excepciones que provocan los errores de tiempo de ejecución anteriores.

  • Exists- Hay dos tipos de salidas: salidas "internas" y salidas "externas". Las salidas internas se activan llamando a la funciónexit/1y hacer que el proceso actual detenga su ejecución. Las salidas externas se llaman conexit/2 y tiene que ver con múltiples procesos en el aspecto concurrente de Erlang.

  • Throw- Un lanzamiento es una clase de excepción que se usa para casos que se espera que maneje el programador. En comparación con las salidas y los errores, realmente no conllevan ningún "bloqueo de ese proceso". intención detrás de ellos, sino que controlan el flujo. Como usa throws mientras espera que el programador los maneje, generalmente es una buena idea documentar su uso dentro de un módulo que los usa.

UNA try ... catch es una forma de evaluar una expresión mientras le permite manejar el caso exitoso, así como los errores encontrados.

La sintaxis general de una expresión try catch es la siguiente.

Sintaxis

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

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

La expresión en el medio try and ofse dice que está protegido. Esto significa que se detectará cualquier tipo de excepción que ocurra dentro de esa llamada. Los patrones y expresiones entre lostry ... of and catch se comportan exactamente de la misma manera que un case ... of.

Finalmente, la parte de captura: aquí, puede reemplazar TypeOfErrorpor error, lanzamiento o salida, para cada tipo respectivo que hemos visto en este capítulo. Si no se proporciona ningún tipo, se asume un lanzamiento.

A continuación se muestran algunos de los errores y las razones del error en Erlang:

Error Tipo de error
badarg Mal argumento. El argumento es de un tipo de datos incorrecto o está mal formado.
badarith Mal argumento en una expresión aritmética.
{badmatch, V} La evaluación de una expresión de coincidencia falló. El valor V no coincidió.
cláusula_función No se encuentra ninguna cláusula de función coincidente al evaluar una llamada de función.
{case_clause, V} No se encuentra ninguna rama coincidente al evaluar una expresión de caso. El valor V no coincidió.
Si cláusula No se encuentra una rama verdadera al evaluar una expresión if.
{try_clause, V} No se encuentra ninguna rama coincidente al evaluar la sección of de una expresión try. El valor V no coincidió.
indef La función no se puede encontrar al evaluar una llamada de función.
{badfun, F} Algo anda mal con una divertida F
{badarity, F} La diversión se aplica al número incorrecto de argumentos. F describe la diversión y las discusiones.
timeout_value El valor de tiempo de espera en una expresión de recepción ... después se evalúa como algo distinto de un número entero o infinito.
noproc Intentando vincular a un proceso inexistente.

A continuación se muestra un ejemplo de cómo se pueden usar estas excepciones y cómo se hacen las cosas.

  • La primera función genera todos los tipos posibles de excepción.

  • Luego escribimos una función contenedora para llamar generate_exception en un intento ... captura la expresión.

Ejemplo

-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.

Si ejecutamos el programa como helloworld: demo (). , obtendremos el siguiente resultado:

Salida

[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]