Erlang (programming language)/Tutorials/Trap exit
Trapping Exit Signals
Trapping Exit Signals is one of the most elegant parts of erlang. Under certain conditions we can cause the error message of a crashing process to be turned into a regular message to another process that is watching. In the example program we construct a monitor-worker relationship. A monitor process is watching a worker process. First we spawn the monitor, then we spawn the worker. We need to link the two processes. Then we change the process flag for trap_exit to true.
start() -> spawn( monitor... spawn( worker...
monitor() -> ... link(worker). process_flag(trap_exit, true). ...
When trap_exit==true then monitor process behaves like a system process and receives exit messages rather than exiting with its linked worker. After configuation, if the worker exits then monitor receives an {EXIT, Pid, Why} message. If the monitor wishes, it could restart the worker or do some other needed action based on the type of exit condition.
In the example code we take the log of 10, 1 and 0. Of course log(10) and log(1) have values but log(0) is undefined and causes the worker process to exit with a badarith(bad arithmatic) error.
Sample Program
%% --- %% trap_exit_test %% a simple demo of using trap_exit %%--- -module(trap_exit_test). -compile(export_all). start() -> Pid = spawn(trap_exit_test, worker, []), register(work, Pid), spawn(trap_exit_test, monitor, [Pid]), work ! {log,10}, sleep(1000), work ! {log,1}, sleep(1000), work ! {log,0}.
monitor(Pid) -> link(Pid), process_flag(trap_exit, true), receive {'EXIT', _Pid, Why} -> io:format("worker exit: ~w ~n",[Why]), exit(monitor_normal_exit) end, monitor(Pid). worker() -> receive {log, Arg} -> Output = math:log(Arg), io:format("log of ~w = ",[Arg]), io:format("~w ~n",[Output]) after 5000 -> exit(time_out) end, worker().
sleep(T) -> receive after T -> ok end.
Sample Output
1> c(trap_exit_test). {ok,trap_exit_test} 2> trap_exit_test:start(). log of 10 = 2.30259 log of 1 = 0.00000e+0 =ERROR REPORT==== 12-Jul-2008::10:40:53 === Error in process <0.37.0> with exit value: {badarith,[{math,log,[0]},{trap_exit_test,worker,0}]} worker exit: {badarith,[{math,log,[0]},{trap_exit_test,worker,0}]} {log,0}