Exception handling idioms
Ulf Wiger
ulf@REDACTED
Thu Aug 25 21:13:19 CEST 2005
Den 2005-08-25 20:21:56 skrev Vance Shipley <vances@REDACTED>:
> What I do is to write the gen_server like this:
> handle_call({Atom, Int, List}, _, State)
> when is_atom(Atom), is_integer(Int), is_list(List) ->
> ...
> {reply, Result, State};
> handle_call(_, {Pid, _Tag}, State) ->
> exit(Pid, badarg),
> {noreply, State}.
My preference is to do this:
handle_call({Atom, Int, List}, _, State)
when is_atom(Atom), is_integer(Int), is_list(List) ->
...
{reply, Result, State};
handle_call(_, _, State) ->
{reply, badarg, State}.
and then a custom call/1 function:
call(Request) ->
case gen_server:call(?SERVER, Request) of
badarg ->
erlang:error(badarg);
Reply ->
Reply
end.
You can substitute 'badarg' for some other value,
as long as it cannot be confused with a good reply.
One way to ensure this is to wrap the replies:
case gen_server:call(?SERVER, Request) of
{error, Reason} ->
erlang:error(Reason);
{reply, Reply} ->
Reply
end.
The advantages of doing it this way are:
- if the client is trapping exits, the call
function must wait for a possible EXIT message.
Then, the error indication will look different
depending on the trap_exit flag.
- erlang:error/1 produces a call backtrace, which
identifies the error nicely as being in the call
function.
- If the client function is re-implemented to do
the job locally, without contacting a server,
the exception is already generated as if it were
a locally executed job.
/Uffe
--
Ulf Wiger
More information about the erlang-questions
mailing list