Error Handling In Erlang by Marcos Benevides
:ID: 22ae9c25-3123-4ed8-b765-369ac89d2942
In Erlang we do exactly the opposite. We build our applications in two parts: a part that solves the problem and a part that corrects errors if they have occurred.
The part that solves the problem is written with as little defensive code as possible; we assume that all arguments to functions are correct and the programs will execute without errors.
The part that corrects errors is often generic, so the same error-correcting code can be used for many different applications. (Armstrong 2013, 201)
Error Handling Semantics
Processes
There are two types of processes: normal processes and system processes. spawn
(see Concurrent Erlang) creates a normal process. A normal process can become a
system process by evaluating the BIF process_flag(trap_exit, true)
.
Link
Linking processes can be thought as an extension of the error handling presented when dealing with Sequential Erlang. We can, if necessary, catch exceptions early in the sequential code, that still won’t make our application fault tolerant.
For one process to observe another, we must create a
link
ormonitor
between the processes. If the linked or monitored processes dies, the observing process is informed.Observing processes work transparently across machine boundaries, so a process running on one machine can monitor the behavior of a process run- ning on a different machine. This is the basis for programming fault-tolerant systems. (Armstrong 2013, 200)
To create links, we call the primitive link(Pid)
, which creates a link between the
calling process and Pid
. So, if Pid1
calls link(Pid2)
, a link is created between Pid1
and
Pid2
.
Pid1 = link(Pid2)
link/1
creates a bi-directional link between the process calling the BIF (Pid1
) and the process linked (Pid2
).spawn_link/3
will yield the same result asspawn/3
followed bylink/1
, only that will do so atomically.unlink/1
removes the link toPid
.
Link Set
The link set of a process P
is the set of processes that are linked to P
.
Groups of Processes That All Die Together
In the previous example, if a single process from the Link Set fails, all the processes from the Set also fail in cascate. Ultimately, the error signals propagate to all the linked processes, and the entire group of linked processes dies.
When an Erlang process fails, it sends an explanation to other processes that are linked to it in the form of a tuple. The tuple contains the atom
EXIT
, thePid
of the failed process, and the error as a complex tuple. (Laurent 2017, 100)
Exit Signals
- A process can termination can be normal or abnormal.
- Normal: When there is no more code to execute.
- Abnormal: When runtime errors occur.
- When a process terminates, it sends a signal to all process its linked to. The
exit signal will contain the following information:
Field Description Sender Identifier The process or port identifier of the process or port that terminated. Receiver Identifier The process or port identifier of the process or port which the exit signal is sent to. The link
flagThis flag will be set indicating that the exit signal was sent due to a link. exit
reason
Error Trapping
If your process is set to trap exits, through a call to
process_flag(trap_exit, true)
, these error reports arrive as messages, rather than just killing your process. (Laurent 2017, 100)
Propagation Semantics
- Processes can trap
exit
signals by calling the BIFprocess_flag(trap_exit, true)
. - Once trapped, the errors are saved in the mailbox.
Pid2
functions as a firewall, stopping errors from propagating to other processes in the system.
Monitors
Monitors are similar to links but with several significant differences.
- Monitors are unidirectional.
A process Pid2
can create a monitor for Pid1
by calling the BIF
erlang:monitor(process, Pid2)
. The function returns a reference Ref
.
- When a monitored process dies, a “down” message (not an
exit
signal) is sent to the monitoring process.