aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2025-02-08 14:53:54 +0100
committerLoïc Hoguin <[email protected]>2025-02-08 14:53:54 +0100
commitfbd680f0f6fb5fe99c4345b838cb42aa1afb3283 (patch)
tree470912c6388453720f41afff413177cc3aecf5c7
parentcc97c770fbe6484b56e661021c4350163349a740 (diff)
downloadcowboy-fbd680f0f6fb5fe99c4345b838cb42aa1afb3283.tar.gz
cowboy-fbd680f0f6fb5fe99c4345b838cb42aa1afb3283.tar.bz2
cowboy-fbd680f0f6fb5fe99c4345b838cb42aa1afb3283.zip
Properly handle external exits of request processes
Because the exit reason doesn't include the stacktrace they were ignored. Now they are properly handled. The error message was changed slightly to accomodate.
-rw-r--r--src/cowboy_stream_h.erl7
-rw-r--r--test/handlers/crash_h.erl3
-rw-r--r--test/plain_handler_SUITE.erl11
3 files changed, 17 insertions, 4 deletions
diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl
index b373344..e384eb0 100644
--- a/src/cowboy_stream_h.erl
+++ b/src/cowboy_stream_h.erl
@@ -138,7 +138,7 @@ info(StreamID, Info={'EXIT', Pid, {{request_error, Reason, _HumanReadable}, _}},
{error_response, Status, #{<<"content-length">> => <<"0">>}, <<>>},
stop
], State);
-info(StreamID, Exit={'EXIT', Pid, {Reason, Stacktrace}}, State=#state{ref=Ref, pid=Pid}) ->
+info(StreamID, Exit={'EXIT', Pid, Reason}, State=#state{ref=Ref, pid=Pid}) ->
Commands0 = [{internal_error, Exit, 'Stream process crashed.'}],
Commands = case Reason of
normal -> Commands0;
@@ -146,9 +146,8 @@ info(StreamID, Exit={'EXIT', Pid, {Reason, Stacktrace}}, State=#state{ref=Ref, p
{shutdown, _} -> Commands0;
_ -> [{log, error,
"Ranch listener ~p, connection process ~p, stream ~p "
- "had its request process ~p exit with reason "
- "~999999p and stacktrace ~999999p~n",
- [Ref, self(), StreamID, Pid, Reason, Stacktrace]}
+ "had its request process ~p exit with reason ~0p~n",
+ [Ref, self(), StreamID, Pid, Reason]}
|Commands0]
end,
%% @todo We are trying to send a 500 response before resetting
diff --git a/test/handlers/crash_h.erl b/test/handlers/crash_h.erl
index b687aba..57d4d85 100644
--- a/test/handlers/crash_h.erl
+++ b/test/handlers/crash_h.erl
@@ -7,6 +7,9 @@
-export([init/2]).
-spec init(_, _) -> no_return().
+init(_, external_exit) ->
+ ct_helper:ignore(?MODULE, init, 2),
+ exit(self(), ct_helper_ignore);
init(_, no_reply) ->
ct_helper:ignore(?MODULE, init, 2),
error(crash);
diff --git a/test/plain_handler_SUITE.erl b/test/plain_handler_SUITE.erl
index 756c0a6..2dc1e23 100644
--- a/test/plain_handler_SUITE.erl
+++ b/test/plain_handler_SUITE.erl
@@ -45,6 +45,7 @@ end_per_group(Name, _) ->
init_dispatch(_) ->
cowboy_router:compile([{"localhost", [
+ {"/crash/external_exit", crash_h, external_exit},
{"/crash/no_reply", crash_h, no_reply},
{"/crash/reply", crash_h, reply}
]}]).
@@ -78,3 +79,13 @@ crash_before_reply(Config) ->
]),
{response, fin, 500, _} = gun:await(ConnPid, Ref),
gun:close(ConnPid).
+
+external_exit_before_reply(Config) ->
+ doc("A plain handler exits externally before a response was sent "
+ "results in a 500 response."),
+ ConnPid = gun_open(Config),
+ Ref = gun:get(ConnPid, "/crash/external_exit", [
+ {<<"accept-encoding">>, <<"gzip">>}
+ ]),
+ {response, fin, 500, _} = gun:await(ConnPid, Ref),
+ gun:close(ConnPid).