[erlang-questions] why is the error reason in a catch/try truncated?

Raimo Niskanen <>
Tue Jan 18 16:53:43 CET 2011


On Tue, Jan 18, 2011 at 04:46:21PM +0100, Raimo Niskanen wrote:
> On Tue, Jan 18, 2011 at 03:52:15PM +0100, Joe Armstrong wrote:
> > I have a program.
> > 
> > When I run the "uncaught" version it prints a very nice error message like
> > this:
> > 
> > > compile_file(File, Args, ParseTree).
> > 
> > {"init terminating in
> > do_boot",{badarg,[{lists,member,[free_index,all_keys]},{ecc_db,add_to_list,2},{ecc_db,store,2},{ecc_pass1,start,2},{ecc_compile,compile_file0,3},{ecc_compile,compile_file,3},{ecc,batch,1},{init,start_it,1}]}}
> > 
> > This tells be exactly were I bombed.
> > 
> > In my "production" version of the code I add wrapper with a catch/try to
> > trap any unwanted errors.
> > So I write:
> > 
> > compile_file(File, Args, ParseTree) ->
> >  case (catch compile_file0(File, Args, ParseTree)) of
> >     {'EXIT', Why} ->
> >         io:format("Compile file:~s aborted with:~p ~n",[File, Why]);
> >     _ ->
> >         ok
> >     end
> > 
> > But when i run this
> > 
> > > compile_file(File, Args, ParseTree).
> > Compile file:first.c aborted with:error badarg
> > 
> > So the Why in the error tuple has lost all the useful information that was
> > in
> > the untrapped code.
> > 
> > To find the error I have to comment out the wrapped version and
> > run the unwrapped version. This is because Why is just the atom
> > badarg and not the more verbose {badarg, ...}
> > 
> > I find this behavior very unhelpfull - am I the only one?
> 
> You must be doing something wrong.
> 
> $ cat test.erl
> -module(test).
> -export([foo/2]).
> foo(T, L) ->
>     catch lists:member(T, L).
> 
> $ erl
> Erlang R14B01 (erts-5.8.2) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
> 
> Eshell V5.8.2  (abort with ^G)
> 1> test:foo(d, [a,b,c|q]).
> {'EXIT',{badarg,[{lists,member,[d,[a,b,c|q]]},
>                  {test,foo,2},
>                  {erl_eval,do_apply,5},
>                  {shell,exprs,7},
>                  {shell,eval_exprs,7},
>                  {shell,eval_loop,3}]}}
> 
> The catch operator returns the whole stackdump.
> 
> If you used the try..catch construct as your subject indicated
> but not your code, it will exclude the stacktrace, which is
> the intended behaviour since constructing the stacktrace
> will cost performance. To get the stacktrace in a try..catch
> you can use erlang:get_stacktrace(). See
> http://erlang.org/doc/reference_manual/expressions.html, section "Try"
> especially the example: Using try to emulate catch Expr:
>   try Expr
>   catch
>       throw:Term -> Term;
>       exit:Reason -> {'EXIT',Reason}
>       error:Reason -> {'EXIT',{Reason,erlang:get_stacktrace()}}
>   end

And see also "Programming Erlang" chapter "4 Exceptions" especially
section "4.9 Stack Traces", by Joe Armstrong ;-)

No, but seriously. It is an optimization so code that just
want to catch an exception will no suffer from the emulator
building the whole stacktrace just to throw it away without
even looking at it.

> 
> > 
> > 
> > /Joe
> 
> -- 
> 
> / Raimo Niskanen, Erlang/OTP, Ericsson AB
> 
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-questions mailing list