diff options
-rw-r--r-- | src/cowboy_clear.erl | 20 | ||||
-rw-r--r-- | src/cowboy_stream_h.erl | 37 | ||||
-rw-r--r-- | src/cowboy_tls.erl | 20 |
3 files changed, 29 insertions, 48 deletions
diff --git a/src/cowboy_clear.erl b/src/cowboy_clear.erl index 7ff5d8b..522ede3 100644 --- a/src/cowboy_clear.erl +++ b/src/cowboy_clear.erl @@ -16,26 +16,16 @@ -behavior(ranch_protocol). -export([start_link/4]). --export([proc_lib_hack/5]). +-export([connection_process/5]). -spec start_link(ranch:ref(), inet:socket(), module(), cowboy:opts()) -> {ok, pid()}. start_link(Ref, Socket, Transport, Opts) -> - Pid = proc_lib:spawn_link(?MODULE, proc_lib_hack, [self(), Ref, Socket, Transport, Opts]), + Pid = proc_lib:spawn_link(?MODULE, connection_process, + [self(), Ref, Socket, Transport, Opts]), {ok, Pid}. --spec proc_lib_hack(pid(), ranch:ref(), inet:socket(), module(), cowboy:opts()) -> ok. -proc_lib_hack(Parent, Ref, Socket, Transport, Opts) -> - try - init(Parent, Ref, Socket, Transport, Opts) - catch - _:normal -> exit(normal); - _:shutdown -> exit(shutdown); - _:Reason = {shutdown, _} -> exit(Reason); - _:Reason -> exit({Reason, erlang:get_stacktrace()}) - end. - --spec init(pid(), ranch:ref(), inet:socket(), module(), cowboy:opts()) -> ok. -init(Parent, Ref, Socket, Transport, Opts) -> +-spec connection_process(pid(), ranch:ref(), inet:socket(), module(), cowboy:opts()) -> ok. +connection_process(Parent, Ref, Socket, Transport, Opts) -> ok = ranch:accept_ack(Ref), init(Parent, Ref, Socket, Transport, Opts, cowboy_http). diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl index 4459679..cf1d38a 100644 --- a/src/cowboy_stream_h.erl +++ b/src/cowboy_stream_h.erl @@ -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 diff --git a/src/cowboy_tls.erl b/src/cowboy_tls.erl index 24e6666..316fc32 100644 --- a/src/cowboy_tls.erl +++ b/src/cowboy_tls.erl @@ -16,26 +16,16 @@ -behavior(ranch_protocol). -export([start_link/4]). --export([proc_lib_hack/5]). +-export([connection_process/5]). -spec start_link(ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> {ok, pid()}. start_link(Ref, Socket, Transport, Opts) -> - Pid = proc_lib:spawn_link(?MODULE, proc_lib_hack, [self(), Ref, Socket, Transport, Opts]), + Pid = proc_lib:spawn_link(?MODULE, connection_process, + [self(), Ref, Socket, Transport, Opts]), {ok, Pid}. --spec proc_lib_hack(pid(), ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> ok. -proc_lib_hack(Parent, Ref, Socket, Transport, Opts) -> - try - init(Parent, Ref, Socket, Transport, Opts) - catch - _:normal -> exit(normal); - _:shutdown -> exit(shutdown); - _:Reason = {shutdown, _} -> exit(Reason); - _:Reason -> exit({Reason, erlang:get_stacktrace()}) - end. - --spec init(pid(), ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> ok. -init(Parent, Ref, Socket, Transport, Opts) -> +-spec connection_process(pid(), ranch:ref(), ssl:sslsocket(), module(), cowboy:opts()) -> ok. +connection_process(Parent, Ref, Socket, Transport, Opts) -> ok = ranch:accept_ack(Ref), case ssl:negotiated_protocol(Socket) of {ok, <<"h2">>} -> |