Skip to content
Erlang

Links, Exit Trapping & 'Let It Crash'

Use link and trap_exit to detect process death and recover.

By EZ4Code Team
linkexitfault-tolerance

Code

-module(keeper).
-export([start/0, child/0]).

start() ->
    process_flag(trap_exit, true),         % convert EXIT signals to messages
    Pid = spawn_link(fun child/0),         % spawn AND link atomically
    keeper_loop(Pid).

keeper_loop(Pid) ->
    receive
        {'EXIT', Pid, Reason} ->
            io:format("child died with ~p, restarting~n", [Reason]),
            NewPid = spawn_link(fun child/0),
            keeper_loop(NewPid);
        {'EXIT', _Other, _Reason} ->
            %% some other linked process died; ignore
            keeper_loop(Pid);
        {stop, From} ->
            exit(Pid, shutdown),
            From ! ok
    end.

child() ->
    timer:sleep(rand:uniform(5000)),
    case rand:uniform(3) of
        1 -> erlang:error(bad_thing);      % crash on purpose
        2 -> exit(normal);                 % 'normal' exits don't propagate
        _ -> exit(bad_luck)                % abnormal exit
    end.

% With trap_exit=true the keeper survives all of these because
% exit signals arrive as {'EXIT', Pid, Reason} messages.

Explanation

link/1 creates a bidirectional link so that if either process dies the other receives an exit signal — by default that signal crashes the receiver too. Setting process_flag(trap_exit, true) converts those signals into {'EXIT', From, Reason} messages, letting the keeper observe crashes without dying itself. This 'let it crash' style — keep the supervisor simple, let workers fail fast — is the heart of Erlang's fault tolerance.

More Erlang Snippets