Search code examples
elixirerlang-otp

How to get notified for any crash from any linked process?


I start multiple (genserver) process in my app though Supervisor, Dynamic supervisor, and sometime simply a direct start_link. Some of them can crash without letting me know when I start the app with iex -S mix. How to make sure I receive all the notification of any crash from any process, if I do not catch it myself? What are the good practice around "letting process crash" while keeping a trace of all the event?

XXX.start_link(ws_uri, __MODULE__, state, [{:name, MyModule}])

Solution

  • From the GenServer docs:

    terminate/2 is called if a callback (except init/1) does one of the following:

    -returns a :stop tuple
    -raises
    -calls Kernel.exit/1
    -returns an invalid value
    -the GenServer traps exits (using Process.flag/2) and the parent process sends an exit signal

    If part of a supervision tree, a GenServer will receive an exit signal when the tree is shutting down. The exit signal is based on the shutdown strategy in the child's specification,
    ...
    ...
    If the GenServer receives an exit signal (that is not :normal) from any process when it is not trapping exits it will exit abruptly with the same reason and so not call terminate/2. Note that a process does NOT trap exits by default and an exit signal is sent when a linked process exits or its node is disconnected.

    Therefore it is not guaranteed that terminate/2 is called when a GenServer exits. For such reasons, we usually recommend important clean-up rules to happen in separated processes either by use of monitoring or by links themselves. There is no cleanup needed when the GenServer controls a port (for example, :gen_tcp.socket) or File.io_device/0, because these will be closed on receiving a GenServer's exit signal and do not need to be closed manually in terminate/2.