diff options
author | Loïc Hoguin <[email protected]> | 2017-09-14 13:42:17 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2017-09-14 13:42:17 +0200 |
commit | 3cbf885961dc93df1b39d2de89f2a871402acbd5 (patch) | |
tree | 8f8f80ea6e6756fb5136cd6eff9bc03ea00cf481 /src/cowboy_stream_h.erl | |
parent | 15ceaf1edff2a68e461fafd8cd77fc7f98918c8a (diff) | |
download | cowboy-3cbf885961dc93df1b39d2de89f2a871402acbd5.tar.gz cowboy-3cbf885961dc93df1b39d2de89f2a871402acbd5.tar.bz2 cowboy-3cbf885961dc93df1b39d2de89f2a871402acbd5.zip |
Improve how we detect request errors
When the request process exits with a {request_error, Reason, Human}
exit reason, Cowboy will return a 400 status code instead of 500.
Cowboy may also return a more specific status code depending on
the error. Currently it may also return 408 or 413.
This should prove to be more solid that looking inside the stack
trace.
Diffstat (limited to 'src/cowboy_stream_h.erl')
-rw-r--r-- | src/cowboy_stream_h.erl | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl index 5113f2e..4459679 100644 --- a/src/cowboy_stream_h.erl +++ b/src/cowboy_stream_h.erl @@ -69,14 +69,17 @@ data(_StreamID, IsFin, Data, State=#state{pid=Pid, read_body_ref=Ref, -spec info(cowboy_stream:streamid(), any(), State) -> {cowboy_stream:commands(), State} when State::#state{}. info(_StreamID, {'EXIT', Pid, normal}, State=#state{pid=Pid}) -> - %% @todo Do we even reach this clause? {[stop], State}; -info(_StreamID, {'EXIT', Pid, {_Reason, [T1, T2|_]}}, State=#state{pid=Pid}) - when element(1, T1) =:= cow_http_hd; element(1, T2) =:= cow_http_hd -> - %% @todo Have an option to enable/disable this specific crash report? +info(_StreamID, {'EXIT', Pid, {{request_error, Reason, _HumanReadable}, _}}, State=#state{pid=Pid}) -> + %% @todo Optionally report the crash to help debugging. %%report_crash(Ref, StreamID, Pid, Reason, Stacktrace), + Status = case Reason of + timeout -> 408; + payload_too_large -> 413; + _ -> 400 + end, %% @todo Headers? Details in body? More stuff in debug only? - {[{error_response, 400, #{<<"content-length">> => <<"0">>}, <<>>}, stop], State}; + {[{error_response, Status, #{<<"content-length">> => <<"0">>}, <<>>}, stop], State}; info(StreamID, Exit = {'EXIT', Pid, {Reason, Stacktrace}}, State=#state{ref=Ref, pid=Pid}) -> report_crash(Ref, StreamID, Pid, Reason, Stacktrace), {[ @@ -162,11 +165,9 @@ report_crash(Ref, StreamID, Pid, Reason, Stacktrace) -> proc_lib_hack(Req, Env, Middlewares) -> try execute(Req, Env, Middlewares) - catch - _:Reason when element(1, Reason) =:= cowboy_handler -> - exit(Reason); - _:Reason -> - exit({Reason, erlang:get_stacktrace()}) + catch _:Reason -> + %% @todo Have a way to identify OTP 20 to not do this twice? + exit({Reason, erlang:get_stacktrace()}) end. %% @todo |