1 min read

Don't let the try catch you

Your process crashed in spite of your super-safe try-catch? How on earth could an error escape out of that jail?

Easy. You didn't RTFM

šŸ’”
"Only exceptions occurring during the evaluation of Exprs can be caught by the catch section. Exceptions occurring in a Body or due to a failed match are not caught."

Now lets see why...

Perhaps you naively did

try decode_request(JsonString) of 
    {ok, ReqMap} ->
        {ok, ValidReq} = validate_request(ReqMap),
        {ok, execute_request(ValidReq)};
    {error, Reason} = Err -> 
        Err
catch ErrClass:ErrReason -> 
    {error, {ErrClass, ErrReason}}
end.

and then for an invalid request your process just crashed. Booom! badmatch

But..but why? You tried, you catched ..you did all they said and nothing??

Now go back and read that documentation excerpt again. Carefully!

To the naive and superficial readers, this try construct may look safe(for Java/.Net devs), but the only safe code is actually only between the try .. of parts of the expression.

Any other code running in the of section or inside an exception body is unprotected and can cause the process to crash!

to make the try more predictable you can rephrase it like this by leaving out the of section

try {ok, ReqMap} = decode_request(JsonString),
    {ok, ValidReq} = validate_request(ReqMap),
    {ok, execute_request(ValidReq)}
catch ErrClass:ErrReason -> 
    {error, {ErrClass, ErrReason}}
end.

Oh, and one more thing:

don't (accidentally maybe)leave out the ErrClass in the exception match because it's equivalent to throwing the error :O

try 1/0
catch 
    Error -> {error, div_by_zero}
end

This won't match any Exception body and just crash with:

** exception error: an error occurred when evaluating an arithmetic expression
     in operator  '/'/2
        called as 1 / 0