[erlang-bugs] handling of uncaught exceptions in behavour callbacks

Daniel Luna <>
Wed Apr 25 15:21:25 CEST 2012

Hi Richard and list,

I personally fully agree that it's a bug, but more importantly a fix
of this would hopefully finally allow me to have stacktraces when
gen_servers die.

It also explains why you sometimes get strange behavior such as
(paraphrasing) "gen_server died due to {bad_return_value,
something_thrown_by_third_party_library}", often without the crash
telling you the type of the gen_server or any information whatsoever
about the stacktrace.

A rewrite of this would be sweet.



On 25 April 2012 04:43, Richard Carlsson <> wrote:
> When gen_server, gen_fsm, etc., make a call to one of the behaviour callback
> functions, these calls are protected by a construct on the following form
> (simplified):
>    case catch Mod:some_callback(...) of
>        ...
>        {'EXIT',Reason} -> exit(Reason);
>        Other -> exit({bad_return_value, Other})
>    end
> When a callback terminates with an exception of type 'error' or 'exit', this
> sort of does the expected thing (although it converts error exceptions to
> exit exceptions, which might or might not be intended). But if the callback
> terminates due to an uncaught throw(Term), it is treated as if the callback
> had returned Term. At best, this is an undocumented and horrible way of
> letting you write callback functions that can do things like throw({reply,
> Reply, NewState}) for nonlocal return out of a deep recursion and back to
> the gen_server code. But I'd like to think that it's simply unintended
> behaviour. (Nothing I could see in the OTP documentation describes what the
> gen_server is supposed to do with exceptions thrown from a callback.)
> The annoyance this causes is that if you use throw(X) for anything within
> the callback (or in library code called by the callback) and you don't make
> sure to wrap your callback in something that catches all throws, any such
> uncaught exception will result in the gen_server process terminating with
> the confusing reason {bad_return_value, X} (and no stack trace to indicate
> where X was thrown from).
> If it can be agreed that this is a bug that should be fixed (and how), we
> could submit a patch.
>    /Richard Carlsson and Samuel Rivas
> _______________________________________________
> erlang-bugs mailing list
> http://erlang.org/mailman/listinfo/erlang-bugs

More information about the erlang-bugs mailing list