[erlang-questions] erlang:raise/3 considered harmful?
Per Hedeland
per@REDACTED
Sat May 14 13:48:20 CEST 2016
Hi,
I happened to want something like erlang:raise/3 for a library function
- I didn't think it existed:-), but found that it does, although it
comes with a semi-dire warning. The loop/3 function below does exactly
what I want, specifically: if the fun provided by the caller of
interate/3 crashes, the caller gets the same exception as if there had
been no try ... catch, can handle it with hir own try/catch or not, but
in any case receives full information about *what* went wrong in hir fun
- all while the "protocol" spoken over the socket remains in sync.
So, to take heed of the warning - is there a way to write an equivalent
function *without* using raise/3 - or should it just be considered a
case of "you really know what you are doing"? I believe I am of
course:-), but I also think that the code below is a perfectly
reasonable implementation of a side-effecty library function, and has no
more to do with debugging or knowing what you're doing than any other
code...
--Per Hedeland
iterate(Sock, Fun, State) ->
gen_tcp:send(Sock, "start"),
loop(Sock, Fun, State).
loop(Sock, Fun, State) ->
case gen_tcp:recv(Sock, 0) of
{ok, "done"} ->
{ok, State};
{ok, Data} ->
Res = try
Fun(Data, State)
catch
Class:Reason ->
gen_tcp:send(Sock, "done"),
erlang:raise(Class, Reason, erlang:get_stacktrace())
end,
case Res of
{continue, NewState} ->
gen_tcp:send(Sock, "continue"),
loop(Sock, Fun, NewState);
{done, NewState} ->
gen_tcp:send(Sock, "done"),
{ok, NewState};
Error ->
gen_tcp:send(Sock, "done"),
Error
end;
Error ->
Error
end.
More information about the erlang-questions
mailing list