[erlang-questions] Exceptions and gen_server

Anton Krasovsky <>
Sat Nov 7 22:33:33 CET 2009


I suppose you'd get better stack trace in my case, but also I didn't
realize you can do exit(Pid, Reason) to a caller process.

Anton

On Sat, Nov 7, 2009 at 9:03 PM, Vance Shipley <> wrote:
> Some time ago I was asking myself whether it was better to
> throw an exception in the client or the server.  In the end
> I decided your method was better because SASL handled it better.
>
>        -Vance
>
> --------------------------------------------------------------------------
> -module(foo_client).
>
> -export([do_local/2, do_remote/2]).
>
> do_local(Pid, Request) ->
>        case gen_server:call(Pid, Request) of
>                {ok, Value} ->
>                        Value;
>                {error, Error} ->
>                        exit(Error)
>        end.
>
> do_remote(Pid, Request) ->
>        gen_server:call(Pid, Request).
>
> --------------------------------------------------------------------------
> -module(foo_server).
>
> -behaviour(gen_server).
>
> -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
>                        terminate/2, code_change/3]).
>
> init(Arg) ->
>        {ok, Arg}.
>
> handle_call(foo_local, _From, State) ->
>        {reply, {ok, 42}, State};
> handle_call(foo_remote, _From, State) ->
>        {reply, 42, State};
> handle_call(bar_local, _From, State) ->
>        {reply, {error, badarg}, State};
> handle_call(bar_remote, {Pid, _Tag}, State) ->
>        exit(Pid, badarg),
>        {noreply, State}.
>
> handle_cast(_Request, State) ->
>        {noreply, State}.
>
> handle_info(_Info, State) ->
>        {noreply, State}.
>
> terminate(_Reason, _State) ->
>        ok.
>
> code_change(_OldVsn, State, _Extra) ->
>        {ok, State}.
>
> --------------------------------------------------------------------------
> 1> application:start(sasl).
> ok
> 2>  {ok, S} = gen_server:start(foo_server, [], []).
> {ok,<0.45.0>}
> 3> foo_client:do_local(S, foo_local).
> 42
> 4> foo_client:do_local(S, bar_local).
> ** exception exit: badarg
>     in function  foo_client:do_local/2
> 5> foo_client:do_remote(S, foo_remote).
> 42
> 6> foo_client:do_remote(S, bar_remote).
> ** exception exit: badarg
> 7>
>
>
> On Fri, Nov 06, 2009 at 03:57:24PM +0000, Anton Krasovsky wrote:
> }  What would be the standard way of returning/throwing an exception in a
> }  result to a gen_server:call?
> }
> }  Would something like that be reasonable:
> }
> }  a() ->
> }  case gen_server:call(..., a) of
> }      {ok, Value} -> Value;
> }      {error, Error} -> throw({error, Error})
> }  end
> }
> }  and
> }
> }  handle_call(a, ...) ->
> }  case ... of
> }      {ok, Value} -> {reply, {ok, Value} , State};
> }      {error, Error} -> {reply, {error, Error} , State}
> }  end
>


More information about the erlang-questions mailing list