[erlang-questions] erlang:raise/3 considered harmful?

Per Hedeland <>
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