[erlang-questions] gen_server:call/3 and timeout handling

Robert Raschke rtrlists@REDACTED
Thu Dec 3 11:15:21 CET 2009

On Wed, Dec 2, 2009 at 10:48 PM, zabrane Mikael <zabrane3@REDACTED> wrote:

> When I use the call "gen_server:call/3 (I mean using the timeout option),
> a timout may occur if the corresponding  "gen_server:handle_call/3" takes
> take too long.
> Then, the whole "gen_server" crashes with an error report.
> What I'd like to achieve is  to "intercept" this "timeout" message in my
> "gen_server" code and handle
> it gracefully without stopping my "gen_server" (eg. by sending back a reply
> with reason = timeout).
> Is this possible? Is there a best practice for that?
I think you would need to wrap the call in a try-catch, as the function call
itself is failing due to the timeout.

For example, using this dummy server:


-export([start_link/0, test/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3,

start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
test() -> gen_server:call(?MODULE, test, 1000).

init([]) -> {ok, []}.

handle_call(test, _From, State) -> {reply, timer:sleep(1500), State}.

handle_cast(_Request, State) -> {noreply, State}.
handle_info(_, State) -> {noreply, State}.
code_change(_Old, State, _Extra) -> {ok, State}.
terminate(_Reason, _State) -> ok.

And in the shell:

Eshell V5.6.5  (abort with ^G)
1> c(timeout_test).
2> timeout_test:start_link().
3> try timeout_test:test() catch Error:Reason -> {Error, Reason} end.

You can obviously also put the try-catch into the function that does the
gen_server:call and return interesting values depending on the catch.

Hope this gets you in the right direction,

More information about the erlang-questions mailing list