|
@@ -21,7 +21,7 @@
|
|
|
-export([terminate/3]).
|
|
|
-export([early_error/5]).
|
|
|
|
|
|
--export([proc_lib_hack/3]).
|
|
|
+-export([request_process/3]).
|
|
|
-export([execute/3]).
|
|
|
-export([resume/5]).
|
|
|
|
|
@@ -47,7 +47,7 @@ init(_StreamID, Req=#{ref := Ref}, Opts) ->
|
|
|
Env = maps:get(env, Opts, #{}),
|
|
|
Middlewares = maps:get(middlewares, Opts, [cowboy_router, cowboy_handler]),
|
|
|
Shutdown = maps:get(shutdown_timeout, Opts, 5000),
|
|
|
- Pid = proc_lib:spawn_link(?MODULE, proc_lib_hack, [Req, Env, Middlewares]),
|
|
|
+ Pid = proc_lib:spawn_link(?MODULE, request_process, [Req, Env, Middlewares]),
|
|
|
{[{spawn, Pid, Shutdown}], #state{ref=Ref, pid=Pid}}.
|
|
|
|
|
|
%% If we receive data and stream is waiting for data:
|
|
@@ -120,7 +120,6 @@ info(_StreamID, SwitchProtocol = {switch_protocol, _, _, _}, State) ->
|
|
|
{[SwitchProtocol], State};
|
|
|
%% Stray message.
|
|
|
info(_StreamID, _Info, State) ->
|
|
|
- %% @todo Cleanup if no reply was sent when stream ends.
|
|
|
{[], State}.
|
|
|
|
|
|
-spec terminate(cowboy_stream:streamid(), cowboy_stream:reason(), #state{}) -> ok.
|
|
@@ -150,24 +149,26 @@ report_crash(Ref, StreamID, Pid, Reason, Stacktrace) ->
|
|
|
|
|
|
%% Request process.
|
|
|
|
|
|
-%% @todo This should wrap with try/catch to get the full error
|
|
|
-%% in the stream handler. Only then can we decide what to do
|
|
|
-%% about it. This means that we should remove any other try/catch
|
|
|
-%% in the request process.
|
|
|
-
|
|
|
-%% This hack is necessary because proc_lib does not propagate
|
|
|
-%% stacktraces by default. This is ugly because we end up
|
|
|
-%% having two try/catch instead of one (the one in proc_lib),
|
|
|
-%% just to add the stacktrace information.
|
|
|
+%% We catch all exceptions in order to add the stacktrace to
|
|
|
+%% the exit reason as it is not propagated by proc_lib otherwise
|
|
|
+%% and therefore not present in the 'EXIT' message. We want
|
|
|
+%% the stacktrace in order to simplify debugging of errors.
|
|
|
+%%
|
|
|
+%% This + the behavior in proc_lib means that we will get a
|
|
|
+%% {Reason, Stacktrace} tuple for every exceptions, instead of
|
|
|
+%% just for errors and throws.
|
|
|
%%
|
|
|
-%% @todo Remove whenever proc_lib propagates stacktraces.
|
|
|
--spec proc_lib_hack(_, _, _) -> _.
|
|
|
-proc_lib_hack(Req, Env, Middlewares) ->
|
|
|
+%% @todo Better spec.
|
|
|
+-spec request_process(_, _, _) -> _.
|
|
|
+request_process(Req, Env, Middlewares) ->
|
|
|
try
|
|
|
execute(Req, Env, Middlewares)
|
|
|
- catch _:Reason ->
|
|
|
- %% @todo Have a way to identify OTP 20 to not do this twice?
|
|
|
- exit({Reason, erlang:get_stacktrace()})
|
|
|
+ catch
|
|
|
+ exit:Reason ->
|
|
|
+ Stacktrace = erlang:get_stacktrace(),
|
|
|
+ erlang:raise(exit, {Reason, Stacktrace}, Stacktrace);
|
|
|
+ Class:Reason ->
|
|
|
+ erlang:raise(Class, Reason, erlang:get_stacktrace())
|
|
|
end.
|
|
|
|
|
|
%% @todo
|