English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Exceptions in Erlang

In any programming language, exception handling is needed to handle runtime errors so that the normal flow of the application can be maintained. Exceptions usually interrupt the normal flow of the application, which is why we need to use exception handling in the application.

Generally, when an exception or error occurs in Erlang, the following message will be displayed.

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

The fault dump will be written to-

erl_crash.dump
init terminating in do_boot()

In Erlang, there are3Types of exceptions-

  • Error−The call will terminate the execution of the current process and include a stack trace when the last function and its parameters are captured. These are the exceptions that cause the above runtime errors.erlang:error(Reason)

  • Exists −There are two types of exits: internal exit and external exit. Internal exit is through calling the function exit/1to trigger and stop the current process from executing. External exits are in exit/2is called and is related to multiple processes in the concurrency aspect of Erlang.

  • Throw −throw is a type of exception used for situations that programmers can handle. Unlike exits and errors, they do not bring any 'crash process!' intent behind them; instead, they control the flow. When you use throws, it is usually best to log their usage in the module where they are used, especially when you expect the programmer to handle the thrown exceptions.

try...catch is a method of evaluating expressions that allows you to handle both successful cases and encountered errors.

try-The general syntax of the catch expression is as follows.

Syntax

try Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 
catch TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

The expression between try and of is called protected. This means that any type of exception that occurs in the call will be caught. The patterns and expressions between try... and catch are completely the same as those in case...

Finally, the catch part - here, you can replace TypeOfError with error, throw, or exit for each type you see in this chapter. If no type is provided, it is assumed to be thrown.

ErrorError type
badarg

The data type of the parameter is incorrect, or the format is incorrect.

badarith

Error parameter in arithmetic expression.

{badmatch,V}

The evaluation of the matching expression fails. The value V does not match.

function_clauseThe matching function clause is not found when evaluating the function call.
{case_clause,V}

The value V does not match when no matching branch is found while calculating the case expression.

if_clauseThe true branch is not found when evaluating the if expression.
{try_clause,V}

The value V does not match when no matching branch is found while calculating the section of the try expression.

undefThe function is not found when evaluating the function call.
{badfun,F}The fun F has a problem
{badarity,F}

A fun is applied to the error count. F describes the fun and the arguments.

timeout_valueThe timeout value in the receive..after expression is calculated as any value other than an integer or infinity.
noprocAttempt to link to a non-existent process.

The following is an example of how to use these exceptions and how to handle them.

  • The first function generates all possible exception types.

  • Then we write a wrapper function that calls generate_exception within a try…catch expression.

Online Example

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

If we run the program's HelloWorld:demo()., we will get the following output

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