Error Handling in Erlang

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 or monitor 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 as spawn/3 followed by link/1, only that will do so atomically.
  • unlink/1 removes the link to Pid.
erlang_process_link.png

Link Set

The link set of a process P is the set of processes that are linked to P.

erlang_link_set.png

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.

erlang_link_set_cascade.png

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, the Pid 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 flag This flag will be set indicating that the exit signal was sent due to a link.
    exit reason  
erlang_error_exit_signals.png

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 BIF process_flag(trap_exit, true).
  • Once trapped, the errors are saved in the mailbox.
erlang_error_trapping.png

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.

erlang_monitor.png
  • When a monitored process dies, a "down" message (not an exit signal) is sent to the monitoring process.
erlang_monitor_error.png

References:

Armstrong, Joe. 2013. “Programming Erlang: Software for a Concurrent World.”
Laurent, Simon St. 2017. Introducing Erlang: Getting Started in Functional Programming. O’Reilly Media, Inc.

Backlinks: