Problem with trap_exit

Alexander Harju <>
Thu Aug 17 18:31:44 CEST 2006


Hi all.
I'm having some problem trying to trap an exit in a gen_fsm.
I've made this small example of the problem attached to this mail. It's 
a gen_server (test_server.erl) that starts a gen_fsm (test_fsm.erl) 
using gen_fsm:start_link(...)
When I by purpose crash the server I expect that the 
handle_info-function in the state-machine to handle the {'EXIT', 
...}-signal since I've turned on trap_exit.
Instead the terminte is called with the reason for the crash.
Why is the signal not traped?
Thanks,
// Alex


The server:

-module(test_server).
-behaviour(gen_server).

-export([start/0, send/1, crash/0, stop/0]).
-export([init/1, handle_call/3, handle_cast/2, terminate/2, handle_info/3]).

-define(debug(S,A,F), io:format("** ~p - ~p [~p] "++S++"\n",
                [?MODULE, F, ?LINE | A])).

start() ->
    gen_server:start({local, ?MODULE}, ?MODULE, [], []).

send(Msg) ->
    gen_server:call(?MODULE, {send, Msg}).

crash() ->
    gen_server:call(?MODULE, crash).

stop() ->
    gen_server:cast(?MODULE, stop).

init([]) ->
    {ok, Pid} = test_fsm:start_link(),
    ?debug("Server: ~p and fsm: ~p started...", [self(), Pid], init),
    {ok, []}.

handle_call({send, Msg}, _From, State) ->
    ?debug("Sending msg: ~p to the fsm", [Msg], handle_call),
    test_fsm:send(Msg),
    {reply, ok, State};

handle_call(crash, _From, State) ->
    ?debug("Server will crash...", [], handle_call),
    Reply = a + b,
    {reply, Reply, State};

handle_call(Msg, _From, State) ->
    ?debug("Received unkown call: ~p", [Msg], handle_call),
    {stop, normal, State}.

handle_cast(stop, State) ->
    {stop, normal, State}.

handle_info(Info, _From, State) ->
    ?debug("Received info: ~p", [Info], handle_info),
    {stop, normal, State}.

terminate(Reason, _State) ->
    ?debug("Terminating with reason: ~p", [Reason], terminate),
    ok.



and the state-machine:

-module(test_fsm).
-behavior(gen_fsm).

-export([start_link/0, stop/0, send/1]).
-export([init/1, state/2, handle_info/3, handle_event/3, terminate/3]).

-define(debug(S,A,F), io:format("** ~p - ~p [~p] "++S++"\n",
                [?MODULE, F, ?LINE | A])).


start_link() ->
    gen_fsm:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    gen_fsm:send_all_state_event(?MODULE, stop).

send(Msg) ->
    gen_fsm:send_event(?MODULE, Msg).

init([]) ->
    process_flag(trap_exit, true),
    {ok, state, []}.

state(Msg, State) ->
    ?debug("Message received: ~p", [Msg], state),
    {next_state, state, State}.


handle_info(Info, StateN, StateD) ->
    ?debug("Received info: ~p in state: ~p, ~p",
       [Info, StateN, StateD], handle_info),
    {next_state, StateN, StateD}.

handle_event(stop, _StateN, StateD) ->
    ?debug("Stopping fsm...", [], first),
    {stop, normal, StateD}.

terminate(Reason, StateN, StateD) ->
    ?debug("Terminating in state: ~p, ~p with reason: ~p",
       [StateN, StateD, Reason], terminate),
    ok.






More information about the erlang-questions mailing list