[erlang-questions] When to catch (was: Module config data and functional programming)

Joe Armstrong erlang@REDACTED
Tue Sep 6 10:24:53 CEST 2011


I just thought of another rule:

"Never return a false answer" - so the answer to "when should I let it crash" is

"you should should crash if the alternative to crashing is to return a
false answer"

Often I use the rule "you should crash if you don't know what to do".

All of this is motivated by some code I saw long, long ago. I was
reading some code.

It read (something like):

    f(...) ->
          ...;
    f(X) ->
          io:format("I don't know what to do in function f X=~p~n", [X]).

Now f was a function of type int() -> int().

The last clause, however returns the atom 'ok' (this is what io:format returns).

f now produces a type incorrect return value (ie it lies about it's
type) - this will cause something else to
crash somewhere else - but we don't want the program to crash
"somewhere else" we want it to crash
*immediately* so we can debug the original error and not the knock-on
error caused by it crashing
"somewhere else".

If you *omit* the last clause of f this is exactly what will happen.

if you want *force* the programmers attention to this error then write
the last clause as exit({an_informative_tuple})

If when you wrote the program you didn't know what to do at this point
in the code - then no amount of catching
in the world will help - all you can do is report the error and return
to some stable state.

This situation occurs extremely often in programming - as you write
code you get to points where
you don't know what to do this is due to bad specifications and
incomplete understanding of the problem.
Programming *is* the art of understanding a problem - once you have
complete understood the problem
the program is in a sense "written" (at least in your head) - it
remains to type it into the machine.
Thus when the problem is not solved you will often not know what to do.

You should always crash immediate to draw attention to the problem and
not make matters worse
(that's while you are developing) - when you ship the product you
change strategy. Add a top level catch
and hide the error from the user - put as much debugging info as
possible in some error log and
tell the developer - try to return the system to a stable state.

Basically, functions should "never lie" ie if they say they are going
to do something
they should do what then say and nothing else - they should crash
rather than lie. This is the programmatic
version of "do no evil".

Hope that helps

/Joe








On Sun, Sep 4, 2011 at 3:31 AM, Daniel Dormont <dan@REDACTED> wrote:
> This was an earlier thread of mine that inspired a new question.
>
> As the months go by I'm getting more comfortable with "let it crash"
> as an idea and seeing its benefits. But it occurs to me: surely there
> are exceptions. Or rather: in order for "let it crash" to work at one
> level of abstraction or functionality, there must be actual
> crash-handling code at a level beneath it. In Erlang, this seems to
> often involve letting individual processes crash and their supervisors
> react accordingly. But perhaps that's not always the right answer. So
> my question is:
>
> When is "catch" the right tool for the job? In the example below,
> Ejabberd's "hooks" handlers use catch when calling functions in
> foreign modules that are (probably) not critical path to whatever it's
> doing. That seems like a pretty decent case to me. Would you agree?
> What are some cases common in Erlang where exceptions need to be
> caught and handled (or ignored) within a single process?
>
> dan
>
> On Fri, Apr 22, 2011 at 1:30 PM, Per Melin <per.melin@REDACTED> wrote:
>> On Fri, Apr 22, 2011 at 4:32 PM, Daniel Dormont
>> <dan@REDACTED> wrote:
>>> It also occurs to me that switching to gen_server would offer another advantage in that it would be easy to recover from crashes in my own code. If I were not to do that though, is the recommended practice just to put a 'catch' call around code that might break?
>>
>> I don't have enough context, but it sounds absolutely unnecessary to
>> create a gen_server for this.
>>
>> I would consider it ejabberd's responsibility to handle any crashes in
>> your code. They have asked you for a callback function and they must
>> consider that it may break. And they are in a better position than you
>> to know how to proceed from a crash here. I did have a look in
>> ejabberd_hooks and they do catch exits from your function. Let it
>> crash.
>>
>> I'm hesitant to touch the question of what is recommended practice
>> since this is the kind of thread where Dr Richard O'Keefe usually
>> comments after a while and turns everyone that posted before him into
>> fools.
>>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list