errors in a loop

126 views Asked by At

Given the following loop on each element of a list:

lists:foldl(fun(X) -> ... end,N,Y),

How to catch the errors and continue to loop on the elements ?

Same question if this code is in a gen_server and if process_flag(trap_exit, true) ?

2

There are 2 answers

0
hdima On BEST ANSWER

Why you just can't use try/catch like this?

1> lists:foldl(
1>     fun (E, A) ->
1>         try E + A
1>         catch
1>             _:_ ->
1>                 A
1>         end
1>      end, 0, [1, 2, 3, 4, a, 6]).
16

Or you can use a decorator function if you want to extract error handling, like this:

1> Sum = fun (E, A) -> E + A end.
#Fun<erl_eval.12.113037538>
2> HandlerFactory = fun (F) ->              
2>     fun (E, A) ->
2>         try F(E, A)
2>         catch
2>             _:_ ->
2>                 A
2>         end
2>     end
2> end.
#Fun<erl_eval.6.13229925>
3> lists:foldl(HandlerFactory(Sum), 0, [1, 2, 3, 4, a, 6]).
16
4> Mul = fun (E, A) -> E * A end.
#Fun<erl_eval.12.113037538>
5> lists:foldl(HandlerFactory(Mul), 1, [1, 2, 3, 4, a, 6]).
144
0
rvirding On

The 1st suggestion by @hdima is the easiest and gives you full control about how to handle different errors/throw etc. For example you may want to allow to throw as a form of non-local exit from the foldl. Are you really certain you want to ignore errors?

HandlerFactory though has an overly complex OO feel about it and seems a bit off. :-) It also severely limits your options.

This code will work within a gen_server as its effect is purely local. Trapping exits will not affect this, or be affected by it, as exits are signals from other processes and these are not caught by try. Turning on trap_exit results in all exit signals from other processes being locally converted to messages which are accessed using receive as any other message.