mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Ensure Websocket errors result in a crash log
This commit is contained in:
parent
c4ed8e2a37
commit
c55db9a8ff
1 changed files with 24 additions and 17 deletions
|
@ -225,9 +225,9 @@ handler_loop(State=#state{socket=Socket, messages={OK, Closed, Error},
|
||||||
websocket_data(State2, HandlerState,
|
websocket_data(State2, HandlerState,
|
||||||
<< SoFar/binary, Data/binary >>);
|
<< SoFar/binary, Data/binary >>);
|
||||||
{Closed, Socket} ->
|
{Closed, Socket} ->
|
||||||
handler_terminate(State, HandlerState, {error, closed});
|
terminate(State, HandlerState, {error, closed});
|
||||||
{Error, Socket, Reason} ->
|
{Error, Socket, Reason} ->
|
||||||
handler_terminate(State, HandlerState, {error, Reason});
|
terminate(State, HandlerState, {error, Reason});
|
||||||
{timeout, TRef, ?MODULE} ->
|
{timeout, TRef, ?MODULE} ->
|
||||||
websocket_close(State, HandlerState, timeout);
|
websocket_close(State, HandlerState, timeout);
|
||||||
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
||||||
|
@ -283,9 +283,9 @@ websocket_payload_loop(State=#state{socket=Socket, transport=Transport,
|
||||||
websocket_payload(State2, HandlerState,
|
websocket_payload(State2, HandlerState,
|
||||||
Type, Len, MaskKey, Rsv, CloseCode, Unmasked, UnmaskedLen, Data);
|
Type, Len, MaskKey, Rsv, CloseCode, Unmasked, UnmaskedLen, Data);
|
||||||
{Closed, Socket} ->
|
{Closed, Socket} ->
|
||||||
handler_terminate(State, HandlerState, {error, closed});
|
terminate(State, HandlerState, {error, closed});
|
||||||
{Error, Socket, Reason} ->
|
{Error, Socket, Reason} ->
|
||||||
handler_terminate(State, HandlerState, {error, Reason});
|
terminate(State, HandlerState, {error, Reason});
|
||||||
{timeout, TRef, ?MODULE} ->
|
{timeout, TRef, ?MODULE} ->
|
||||||
websocket_close(State, HandlerState, timeout);
|
websocket_close(State, HandlerState, timeout);
|
||||||
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
{timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) ->
|
||||||
|
@ -339,9 +339,9 @@ handler_call(State=#state{handler=Handler}, HandlerState,
|
||||||
ok ->
|
ok ->
|
||||||
NextState(State, HandlerState2, RemainingData);
|
NextState(State, HandlerState2, RemainingData);
|
||||||
stop ->
|
stop ->
|
||||||
handler_terminate(State, HandlerState2, stop);
|
terminate(State, HandlerState2, stop);
|
||||||
Error = {error, _} ->
|
Error = {error, _} ->
|
||||||
handler_terminate(State, HandlerState2, Error)
|
terminate(State, HandlerState2, Error)
|
||||||
end;
|
end;
|
||||||
{reply, Payload, HandlerState2, hibernate} ->
|
{reply, Payload, HandlerState2, hibernate} ->
|
||||||
case websocket_send(Payload, State) of
|
case websocket_send(Payload, State) of
|
||||||
|
@ -349,14 +349,15 @@ handler_call(State=#state{handler=Handler}, HandlerState,
|
||||||
NextState(State#state{hibernate=true},
|
NextState(State#state{hibernate=true},
|
||||||
HandlerState2, RemainingData);
|
HandlerState2, RemainingData);
|
||||||
stop ->
|
stop ->
|
||||||
handler_terminate(State, HandlerState2, stop);
|
terminate(State, HandlerState2, stop);
|
||||||
Error = {error, _} ->
|
Error = {error, _} ->
|
||||||
handler_terminate(State, HandlerState2, Error)
|
terminate(State, HandlerState2, Error)
|
||||||
end;
|
end;
|
||||||
{stop, HandlerState2} ->
|
{stop, HandlerState2} ->
|
||||||
websocket_close(State, HandlerState2, stop)
|
websocket_close(State, HandlerState2, stop)
|
||||||
catch Class:Reason ->
|
catch Class:Reason ->
|
||||||
_ = websocket_close(State, HandlerState, {crash, Class, Reason}),
|
websocket_send_close(State, {crash, Class, Reason}),
|
||||||
|
handler_terminate(State, HandlerState, {crash, Class, Reason}),
|
||||||
erlang:raise(Class, Reason, erlang:get_stacktrace())
|
erlang:raise(Class, Reason, erlang:get_stacktrace())
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -389,9 +390,13 @@ is_close_frame({close, _, _}) -> true;
|
||||||
is_close_frame(_) -> false.
|
is_close_frame(_) -> false.
|
||||||
|
|
||||||
-spec websocket_close(#state{}, any(), terminate_reason()) -> no_return().
|
-spec websocket_close(#state{}, any(), terminate_reason()) -> no_return().
|
||||||
websocket_close(State=#state{socket=Socket, transport=Transport, extensions=Extensions},
|
websocket_close(State, HandlerState, Reason) ->
|
||||||
HandlerState, Reason) ->
|
websocket_send_close(State, Reason),
|
||||||
case Reason of
|
terminate(State, HandlerState, Reason).
|
||||||
|
|
||||||
|
websocket_send_close(#state{socket=Socket, transport=Transport,
|
||||||
|
extensions=Extensions}, Reason) ->
|
||||||
|
_ = case Reason of
|
||||||
Normal when Normal =:= stop; Normal =:= timeout ->
|
Normal when Normal =:= stop; Normal =:= timeout ->
|
||||||
Transport:send(Socket, cow_ws:frame({close, 1000, <<>>}, Extensions));
|
Transport:send(Socket, cow_ws:frame({close, 1000, <<>>}, Extensions));
|
||||||
{error, badframe} ->
|
{error, badframe} ->
|
||||||
|
@ -405,10 +410,12 @@ websocket_close(State=#state{socket=Socket, transport=Transport, extensions=Exte
|
||||||
{remote, Code, _} ->
|
{remote, Code, _} ->
|
||||||
Transport:send(Socket, cow_ws:frame({close, Code, <<>>}, Extensions))
|
Transport:send(Socket, cow_ws:frame({close, Code, <<>>}, Extensions))
|
||||||
end,
|
end,
|
||||||
handler_terminate(State, HandlerState, Reason).
|
ok.
|
||||||
|
|
||||||
-spec handler_terminate(#state{}, any(), terminate_reason()) -> no_return().
|
-spec terminate(#state{}, any(), terminate_reason()) -> no_return().
|
||||||
handler_terminate(#state{handler=Handler},
|
terminate(State, HandlerState, Reason) ->
|
||||||
HandlerState, Reason) ->
|
handler_terminate(State, HandlerState, Reason),
|
||||||
cowboy_handler:terminate(Reason, undefined, HandlerState, Handler),
|
|
||||||
exit(normal).
|
exit(normal).
|
||||||
|
|
||||||
|
handler_terminate(#state{handler=Handler}, HandlerState, Reason) ->
|
||||||
|
cowboy_handler:terminate(Reason, undefined, HandlerState, Handler).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue