mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Send a meaningful error to error_logger on handler crashes.
Inspired by gen_server and friends. Should fix issue #13.
This commit is contained in:
parent
548a9a15b8
commit
4c4030a792
1 changed files with 39 additions and 20 deletions
|
@ -172,40 +172,59 @@ dispatch(Req=#http_req{host=Host, path=Path},
|
||||||
-spec handler_init(Req::#http_req{}, State::#state{}) -> ok.
|
-spec handler_init(Req::#http_req{}, State::#state{}) -> ok.
|
||||||
handler_init(Req, State=#state{
|
handler_init(Req, State=#state{
|
||||||
transport=Transport, handler={Handler, Opts}}) ->
|
transport=Transport, handler={Handler, Opts}}) ->
|
||||||
case catch Handler:init({Transport:name(), http}, Req, Opts) of
|
try Handler:init({Transport:name(), http}, Req, Opts) of
|
||||||
{ok, Req2, HandlerState} ->
|
{ok, Req2, HandlerState} ->
|
||||||
handler_loop(HandlerState, Req2, State);
|
handler_loop(HandlerState, Req2, State);
|
||||||
%% @todo {upgrade, transport, Module}
|
%% @todo {upgrade, transport, Module}
|
||||||
{upgrade, protocol, Module} ->
|
{upgrade, protocol, Module} ->
|
||||||
Module:upgrade(Handler, Opts, Req);
|
Module:upgrade(Handler, Opts, Req)
|
||||||
{'EXIT', _Reason} ->
|
catch Class:Reason ->
|
||||||
error_terminate(500, State)
|
error_terminate(500, State),
|
||||||
|
error_logger:error_msg(
|
||||||
|
"** Handler ~p terminating in init/3 for the reason ~p:~p~n"
|
||||||
|
"** Options were ~p~n** Request was ~p~n** Stacktrace: ~p~n~n",
|
||||||
|
[Handler, Class, Reason, Opts, Req, erlang:get_stacktrace()])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec handler_loop(HandlerState::term(), Req::#http_req{},
|
-spec handler_loop(HandlerState::term(), Req::#http_req{},
|
||||||
State::#state{}) -> ok.
|
State::#state{}) -> ok.
|
||||||
handler_loop(HandlerState, Req, State=#state{handler={Handler, _Opts}}) ->
|
handler_loop(HandlerState, Req, State=#state{handler={Handler, Opts}}) ->
|
||||||
case catch Handler:handle(Req#http_req{resp_state=waiting},
|
try Handler:handle(Req#http_req{resp_state=waiting}, HandlerState) of
|
||||||
HandlerState) of
|
|
||||||
{ok, Req2, HandlerState2} ->
|
{ok, Req2, HandlerState2} ->
|
||||||
handler_terminate(HandlerState2, Req2, State);
|
handler_terminate(HandlerState2, Req2, State)
|
||||||
{'EXIT', _Reason} ->
|
catch Class:Reason ->
|
||||||
terminate(State)
|
terminate(State),
|
||||||
|
error_logger:error_msg(
|
||||||
|
"** Handler ~p terminating in handle/2 for the reason ~p:~p~n"
|
||||||
|
"** Options were ~p~n** Handler state was ~p~n"
|
||||||
|
"** Request was ~p~n** Stacktrace: ~p~n~n",
|
||||||
|
[Handler, Class, Reason, Opts,
|
||||||
|
HandlerState, Req, erlang:get_stacktrace()])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec handler_terminate(HandlerState::term(), Req::#http_req{},
|
-spec handler_terminate(HandlerState::term(), Req::#http_req{},
|
||||||
State::#state{}) -> ok.
|
State::#state{}) -> ok.
|
||||||
handler_terminate(HandlerState, Req=#http_req{buffer=Buffer},
|
handler_terminate(HandlerState, Req=#http_req{buffer=Buffer},
|
||||||
State=#state{handler={Handler, _Opts}}) ->
|
State=#state{handler={Handler, Opts}}) ->
|
||||||
HandlerRes = (catch Handler:terminate(
|
try
|
||||||
Req#http_req{resp_state=locked}, HandlerState)),
|
HandlerRes = Handler:terminate(Req#http_req{resp_state=locked},
|
||||||
BodyRes = ensure_body_processed(Req),
|
HandlerState),
|
||||||
RespRes = ensure_response(Req, State),
|
BodyRes = ensure_body_processed(Req),
|
||||||
case {HandlerRes, BodyRes, RespRes, State#state.connection} of
|
RespRes = ensure_response(Req, State),
|
||||||
{ok, ok, ok, keepalive} ->
|
case {HandlerRes, BodyRes, RespRes, State#state.connection} of
|
||||||
?MODULE:parse_request(State#state{buffer=Buffer});
|
{ok, ok, ok, keepalive} ->
|
||||||
_Closed ->
|
?MODULE:parse_request(State#state{buffer=Buffer});
|
||||||
terminate(State)
|
_Closed ->
|
||||||
|
terminate(State)
|
||||||
|
end
|
||||||
|
catch Class:Reason ->
|
||||||
|
terminate(State),
|
||||||
|
error_logger:error_msg(
|
||||||
|
"** Handler ~p terminating in terminate/2 for the reason ~p:~p~n"
|
||||||
|
"** Options were ~p~n** Handler state was ~p~n"
|
||||||
|
"** Request was ~p~n** Stacktrace: ~p~n~n",
|
||||||
|
[Handler, Class, Reason, Opts,
|
||||||
|
HandlerState, Req, erlang:get_stacktrace()])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec ensure_body_processed(Req::#http_req{}) -> ok | close.
|
-spec ensure_body_processed(Req::#http_req{}) -> ok | close.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue