[erlang-questions] When to return {ok, Value} or just the Value

David Mercer dmercer@REDACTED
Tue Nov 15 22:56:41 CET 2011

On Tuesday, November 15, 2011, Richard Carlsson wrote:

> On 2011-11-15 18:35, Fred Hebert wrote:
> >  1. I tend to use exit/1 when my semantics are 'this process is done
> >     running, nothing more to do here'.
> >  2. I use 'error/1' when the semantics are 'there is likely an error
> in
> >     code that will require some programmer to change what they do'.
> >  3. 'throw/1' is usually something I use in a module-local manner for
> >     non-local returns for exceptions I expect to handle in-module.
> >  4. I use {error, Something} when I need to express some
> >     exceptional-but-not-deadly case to the user, something they might
> >     know how to handle and fix, or a boundary condition that they
> might
> >     expect. It's not deadly or game changing, but it's not a normal
> >     result either,
> >
> > That's the general way I picked after researching exceptions and
> their
> > meaning when writing Learn You Some Erlang. Different people who
> worked
> > on Erlang seem to disagree on the semantics of throw vs. error
> (although
> > they seemed to agree on exits), so it's just not exactly simple.

I have no problem with throw vs. error/exit.  Throw is a non-local return;
no problem; it has its uses and I use it when appropriate.  This issue I
have with error vs. exit is that exit seems to be less severe in its
description (this process is done vs. there is an error), yet the
description of what happens in each case is reversed (killing the process
sounds more severe than propagating an error), and, in the end, they have
the same effect (the process dies if not caught).

> Yes, this is the way the different exception classes should be used:
>    * 'exit' for when the process ought to terminate and propagate the
> signal to anyone who's linked to it.
>    * 'error' for run-time errors (no matter whether it's compiler
> generated as when no function clause can match or whether it's because
> your complicated assertion fails, it should be an error).

But this has the effect of terminating the process and propagating the
signal to anyone who's linked to it, just like exit.

>    * 'throw' for nonlocal returns and for the kind of interface where
> you'd like to return a plain value in the normal case but where there
> are some predictable failure cases like throw({not_found, File}) that
> may happen occasionally and that you want to document so that an
> interested user can catch them while uninterested users can simply
> program for the success case.

What criteria should I use in deciding whether an error should terminate the
process (exit) or not (error)?  Either way, if not caught, it terminates the
process, and, if caught, it doesn't.  If I'm writing a function and there is
an error, why would I decide, "this error should terminate the process" and
"this error should not"?  The function usually isn't even process-aware;
it's a function that does something; or not, and then it errors.  It doesn't
care whether it is part of a supervision tree or linked web of processes; it
just wants to signal an error, and let the caller decide whether to catch it
or crash.  Why is the erroring function giving a hint to the caller as to
how to handle its errors, and, really, what does the hint even mean, since
it seems to make no effective difference?

Please advise.  Thank-you.



More information about the erlang-questions mailing list