Erlang - Exceções
O tratamento de exceções é necessário em qualquer linguagem de programação para tratar os erros de tempo de execução de forma que o fluxo normal do aplicativo possa ser mantido. A exceção normalmente interrompe o fluxo normal do aplicativo, razão pela qual precisamos usar o tratamento de exceções em nosso aplicativo.
Normalmente, quando ocorre uma exceção ou erro em Erlang, a seguinte mensagem será exibida.
{"init terminating in do_boot", {undef,[{helloworld,start,[],[]},
{init,start_it,1,[]},{init,start_em,1,[]}]}}
Crash dump será gravado em -
erl_crash.dump
init terminating in do_boot ()
Em Erlang, existem 3 tipos de exceções -
Error - Ligando erlang:error(Reason)encerrará a execução no processo atual e incluirá um rastreamento de pilha das últimas funções chamadas com seus argumentos quando você o capturar. Esses são os tipos de exceções que provocam os erros de tempo de execução acima.
Exists- Existem dois tipos de saídas: saídas 'internas' e saídas 'externas'. As saídas internas são acionadas chamando a funçãoexit/1e fazer com que o processo atual interrompa sua execução. As saídas externas são chamadas comexit/2 e tem a ver com vários processos no aspecto simultâneo de Erlang.
Throw- Um lançamento é uma classe de exceção usada para casos que se espera que o programador trate. Em comparação com saídas e erros, eles não trazem nenhum 'travamento desse processo!' intenção por trás deles, mas ao invés disso, eles controlam o fluxo. Conforme você usa throws enquanto espera que o programador os controle, geralmente é uma boa ideia documentar seu uso dentro de um módulo que os usa.
UMA try ... catch é uma forma de avaliar uma expressão enquanto permite lidar com o caso de sucesso e também com os erros encontrados.
A sintaxe geral de uma expressão try catch é a seguinte.
Sintaxe
try Expression of
SuccessfulPattern1 [Guards] ->
Expression1;
SuccessfulPattern2 [Guards] ->
Expression2
catch
TypeOfError:ExceptionPattern1 ->
Expression3;
TypeOfError:ExceptionPattern2 ->
Expression4
end
A expressão entre try and ofé dito ser protegido. Isso significa que qualquer tipo de exceção que aconteça nessa chamada será detectada. Os padrões e expressões entre ostry ... of and catch se comportar exatamente da mesma maneira que um case ... of.
Finalmente, a parte catch - aqui, você pode substituir TypeOfErrorpor erro, lançamento ou saída, para cada tipo respectivo que vimos neste capítulo. Se nenhum tipo for fornecido, um lançamento é assumido.
A seguir estão alguns dos erros e os motivos dos erros em Erlang -
Erro | Tipo de Erro |
---|---|
badarg | Argumento ruim. O argumento tem tipo de dados incorreto ou está mal formado. |
Badarith | Argumento ruim em uma expressão aritmética. |
{badmatch, V} | A avaliação de uma expressão de correspondência falhou. O valor V não correspondeu. |
function_clause | Nenhuma cláusula de função correspondente é encontrada ao avaliar uma chamada de função. |
{case_clause, V} | Nenhuma ramificação correspondente foi encontrada ao avaliar uma expressão case. O valor V não correspondeu. |
oração condicional | Nenhuma ramificação verdadeira é encontrada ao avaliar uma expressão if. |
{try_clause, V} | Nenhuma ramificação correspondente foi encontrada ao avaliar a seção de uma expressão try. O valor V não correspondeu. |
undef | A função não pode ser encontrada ao avaliar uma chamada de função. |
{badfun, F} | Algo está errado com um divertido F |
{badarity, F} | Uma diversão é aplicada ao número errado de argumentos. F descreve a diversão e os argumentos. |
timeout_value | O valor de tempo limite em uma expressão receive..after é avaliado como algo diferente de um inteiro ou infinito. |
noproc | Tentando vincular a um processo não existente. |
A seguir está um exemplo de como essas exceções podem ser usadas e como as coisas são feitas.
A primeira função gera todos os tipos possíveis de uma exceção.
Em seguida, escrevemos uma função de wrapper para chamar generate_exception em uma expressão try ... catch.
Exemplo
-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.
Se executarmos o programa como helloworld: demo (). , obteremos a seguinte saída -
Resultado
[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]