Links, Monitors & Fault Tolerance

If a linked process exits with a reason other than :normal, the linked process also exits — unless it traps exits:

30.1 Links — bidirectional, crash propagation

If a linked process exits with a reason other than :normal, the linked process also exits — unless it traps exits:

spawn_link(fn -> raise "boom" end)   # crashes the caller too!
Process.link(pid); Process.unlink(pid)
Process.flag(:trap_exit, true)
pid = spawn_link(fn -> exit(:crash) end)
receive do
  {:EXIT, ^pid, reason} -> IO.puts("Child died: #{inspect(reason)}")
end

30.2 Monitors — unidirectional, notification only

{pid, ref} = spawn_monitor(fn -> exit(:oops) end)
receive do
  {:DOWN, ^ref, :process, ^pid, reason} -> IO.puts("Down: #{inspect(reason)}")
end
ref = Process.monitor(pid); Process.demonitor(ref, [:flush])

30.3 Exit reasons

normal termination — linked processes not affected :shutdown / {:shutdown, term} orderly shutdown (no error report) untrappable kill (Process.exit(pid,:kill)) → linked see :killed abnormal — propagates through links

30.4 "Let it crash"

Don't write defensive code for every possible failure. Write the happy path, let unexpected errors crash the process, and let a supervisor restart it in a known good state. Errors are isolated per process.

30.5 Aliases (OTP 24+)

Process.alias/0 creates a reply-only address that can be deactivated — used internally by GenServer.call to avoid late replies.