[erlang-questions] Best practices for handling invalid / unexpected messages

Ciprian Dorin Craciun ciprian.craciun@REDACTED
Fri May 13 22:34:11 CEST 2011


On Fri, May 13, 2011 at 23:20, Joe Armstrong <erlang@REDACTED> wrote:
> No easy answer:
>
> During development:
>
>     Crash loudly - print lots of information about why you crashed
>     do init:stop() or erlang:halt() *force* the programmer to fix the code
>
> During production
>
>     Crash silently - put lots of error in the log and send rude email to
> programmer
>     if you can recover do so. If you cannot recover tell the user as
> politely as possible.
>     *never* present the user with internal error message (this is most
> unprofessional)

    Interesting. The only problem is how to achieve this without
writing too much boilerplate code?

    For example it would have been nice to have a return value like
`{error, Reason, NewState}` from callbacks like `handle_call`, etc.;
which depending on the running environment either "dispatches"
`{reply, {error, Reason}, NewState}`, or `{stop, {error, Reason},
NewState}`. But as such a solution doesn't exist I could just create
three generic functions like `handle_call_error (Reason, NewState)`
that is called from within `handle_call` in a tail position, thus
achieving the same outcome.

    Any other ideas?


> What you do with an error thus depends upon the context where it occurs -
> basically
> tell the programmer the truth and give them all the info needed to fix the
> error, while
> apologizing to the end user ... send an email to the project manager telling
> the code
> is broken if you want the programmer to fix it :-)
>
> /Joe

    A similar approach is done in `web2py` I think, where each
unhandled exception that bubbles outside the callback automatically
creates a bug ticket :)

    Thanks!
    Ciprian.


> On Fri, May 13, 2011 at 9:59 PM, Jachym Holecek <freza@REDACTED>
> wrote:
>>
>> # Ciprian Dorin Craciun 2011-05-13:
>> >     Lately I've started programming a bit more seriously in Erlang,
>> > and after creating a few `gen_server` or `gen_fsm` components, I've
>> > started wondering what is the best way to handle unexpected or invalid
>> > requests / messages. [...]
>> >
>> >     I think of three possibilities:
>> >     * reply back with an error:
>>
>> Yep, this is what I do:
>>
>>  handle_call(_, _, State) ->
>>      {reply, {error, bad_request}, State}.
>>
>>  handle_info(_, State) ->
>>      {noreply, State}.
>>
>> It's similar with gen_fsm & custom processes.
>>
>> >     Now each of these have advantages or disadvantages:
>> >
>> >     * the first one is "polite" to the caller, letting him retry,
>> >       but could lead to hidden bugs if the caller doesn't check
>> >       the return term;
>>
>> It also helps forward-compatibility in presence of hot code upgrades.
>>
>> >     Furthermore, let's say a process depends in his operation on
>> > another process, should it link the dependency process, should it
>> > monitor, or should it just fail on call?
>>
>> Depends on how tightly they're bound together. Linking them means "one
>> can't live without the other even for a second", monitoring means "one
>> is vaguely interested if the other is still alive" (often to clean up
>> some mess when the other dies), fail on call means "ok, I need you to
>> handle my request now, but generally I don't really care about you".
>>
>> The last option is by far the most common, the other two are employed
>> tactically in cases where it matters.
>>
>> HTH,
>>        -- Jachym
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list