mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
No longer use erlang:get_stacktrace/0
It has been deprecated in OTP and the new way is available on all supported OTP versions.
This commit is contained in:
parent
3b85b808ae
commit
3a7232b019
12 changed files with 79 additions and 137 deletions
|
@ -53,9 +53,7 @@ normal::
|
|||
|
||||
{crash, Class, Reason}::
|
||||
A crash occurred in the handler. `Class` and `Reason` can be
|
||||
used to obtain more information about the crash. The function
|
||||
`erlang:get_stacktrace/0` can also be called to obtain the
|
||||
stacktrace of the process when the crash occurred.
|
||||
used to obtain more information about the crash.
|
||||
|
||||
== Exports
|
||||
|
||||
|
|
|
@ -65,9 +65,7 @@ stop::
|
|||
|
||||
{crash, Class, Reason}::
|
||||
A crash occurred in the handler. `Class` and `Reason` can be
|
||||
used to obtain more information about the crash. The function
|
||||
`erlang:get_stacktrace/0` can also be called to obtain the
|
||||
stacktrace of the process when the crash occurred.
|
||||
used to obtain more information about the crash.
|
||||
|
||||
== Changelog
|
||||
|
||||
|
|
|
@ -76,9 +76,7 @@ normal::
|
|||
|
||||
{crash, Class, Reason}::
|
||||
A crash occurred in the handler. `Class` and `Reason` can be
|
||||
used to obtain more information about the crash. The function
|
||||
`erlang:get_stacktrace/0` can also be called to obtain the
|
||||
stacktrace of the process when the crash occurred.
|
||||
used to obtain more information about the crash.
|
||||
|
||||
== REST callbacks
|
||||
|
||||
|
|
|
@ -112,9 +112,7 @@ timeout::
|
|||
|
||||
{crash, Class, Reason}::
|
||||
A crash occurred in the handler. `Class` and `Reason` can be
|
||||
used to obtain more information about the crash. The function
|
||||
`erlang:get_stacktrace/0` can also be called to obtain the
|
||||
stacktrace of the process when the crash occurred.
|
||||
used to obtain more information about the crash.
|
||||
|
||||
{error, badencoding}::
|
||||
A text frame was sent by the client with invalid encoding. All
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
-module(cowboy_handler).
|
||||
-behaviour(cowboy_middleware).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([execute/2]).
|
||||
-export([terminate/4]).
|
||||
|
||||
|
@ -46,10 +42,9 @@ execute(Req, Env=#{handler := Handler, handler_opts := HandlerOpts}) ->
|
|||
Mod:upgrade(Req2, Env, Handler, State);
|
||||
{Mod, Req2, State, Opts} ->
|
||||
Mod:upgrade(Req2, Env, Handler, State, Opts)
|
||||
catch Class:Reason ->
|
||||
StackTrace = erlang:get_stacktrace(),
|
||||
catch Class:Reason:Stacktrace ->
|
||||
terminate({crash, Class, Reason}, Req, HandlerOpts, Handler),
|
||||
erlang:raise(Class, Reason, StackTrace)
|
||||
erlang:raise(Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
-spec terminate(any(), Req | undefined, any(), module()) -> ok when Req::cowboy_req:req().
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
|
||||
-module(cowboy_http).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([init/6]).
|
||||
|
||||
-export([system_continue/3]).
|
||||
|
@ -335,10 +331,10 @@ after_parse({request, Req=#{streamid := StreamID, method := Method,
|
|||
end,
|
||||
State = set_timeout(State1, idle_timeout),
|
||||
parse(Buffer, commands(State, StreamID, Commands))
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(init,
|
||||
[StreamID, Req, Opts],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
early_error(500, State0, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:init/3.'}, Req),
|
||||
parse(Buffer, State0)
|
||||
|
@ -357,10 +353,10 @@ after_parse({data, StreamID, IsFin, Data, State0=#state{opts=Opts, buffer=Buffer
|
|||
end),
|
||||
State = update_flow(IsFin, Data, State1#state{streams=Streams}),
|
||||
parse(Buffer, commands(State, StreamID, Commands))
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(data,
|
||||
[StreamID, IsFin, Data, StreamState0],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
%% @todo Should call parse after this.
|
||||
stream_terminate(State0, StreamID, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:data/4.'})
|
||||
|
@ -904,10 +900,10 @@ info(State=#state{opts=Opts, streams=Streams0}, StreamID, Msg) ->
|
|||
Streams = lists:keyreplace(StreamID, #stream.id, Streams0,
|
||||
Stream#stream{state=StreamState}),
|
||||
commands(State#state{streams=Streams}, StreamID, Commands)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(info,
|
||||
[StreamID, Msg, StreamState0],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
stream_terminate(State, StreamID, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:info/3.'})
|
||||
end;
|
||||
|
@ -1286,10 +1282,10 @@ stream_terminate(State0=#state{opts=Opts, in_streamid=InStreamID, in_state=InSta
|
|||
stream_call_terminate(StreamID, Reason, StreamState, #state{opts=Opts}) ->
|
||||
try
|
||||
cowboy_stream:terminate(StreamID, Reason, StreamState)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(terminate,
|
||||
[StreamID, Reason, StreamState],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts)
|
||||
Class, Exception, Stacktrace), Opts)
|
||||
end.
|
||||
|
||||
maybe_req_close(#state{opts=#{http10_keepalive := false}}, _, 'HTTP/1.0') ->
|
||||
|
@ -1386,10 +1382,10 @@ early_error(StatusCode0, #state{socket=Socket, transport=Transport,
|
|||
%% @todo Technically we allow the sendfile tuple.
|
||||
RespBody
|
||||
])
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(early_error,
|
||||
[StreamID, Reason, PartialReq, Resp, Opts],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
%% We still need to send an error response, so send what we initially
|
||||
%% wanted to send. It's better than nothing.
|
||||
Transport:send(Socket, cow_http:response(StatusCode0,
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
|
||||
-module(cowboy_http2).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([init/6]).
|
||||
-export([init/10]).
|
||||
-export([init/12]).
|
||||
|
@ -384,10 +380,10 @@ data_frame(State0=#state{opts=Opts, flow=Flow, streams=Streams}, StreamID, IsFin
|
|||
flow=max(0, StreamFlow - Size), state=StreamState}}},
|
||||
StreamID),
|
||||
commands(State, StreamID, Commands)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(data,
|
||||
[StreamID, IsFin, Data, StreamState0],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
reset_stream(State0, StreamID, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:data/4.'})
|
||||
end;
|
||||
|
@ -491,10 +487,10 @@ headers_frame(State=#state{opts=Opts, streams=Streams}, StreamID, Req) ->
|
|||
commands(State#state{
|
||||
streams=Streams#{StreamID => #stream{state=StreamState}}},
|
||||
StreamID, Commands)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(init,
|
||||
[StreamID, Req, Opts],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
reset_stream(State, StreamID, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:init/3.'})
|
||||
end.
|
||||
|
@ -518,10 +514,10 @@ early_error(State0=#state{ref=Ref, opts=Opts, peer=Peer},
|
|||
try cowboy_stream:early_error(StreamID, Reason, PartialReq, Resp, Opts) of
|
||||
{response, StatusCode, RespHeaders, RespBody} ->
|
||||
send_response(State0, StreamID, StatusCode, RespHeaders, RespBody)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(early_error,
|
||||
[StreamID, Reason, PartialReq, Resp, Opts],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
%% We still need to send an error response, so send what we initially
|
||||
%% wanted to send. It's better than nothing.
|
||||
send_headers(State0, StreamID, fin, StatusCode0, RespHeaders0)
|
||||
|
@ -579,10 +575,10 @@ info(State=#state{opts=Opts, http2_machine=HTTP2Machine, streams=Streams}, Strea
|
|||
{Commands, StreamState} ->
|
||||
commands(State#state{streams=Streams#{StreamID => Stream#stream{state=StreamState}}},
|
||||
StreamID, Commands)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(info,
|
||||
[StreamID, Msg, StreamState0],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts),
|
||||
Class, Exception, Stacktrace), Opts),
|
||||
reset_stream(State, StreamID, {internal_error, {Class, Exception},
|
||||
'Unhandled exception in cowboy_stream:info/3.'})
|
||||
end;
|
||||
|
@ -1030,10 +1026,10 @@ terminate_stream(State=#state{flow=Flow, streams=Streams0, children=Children0},
|
|||
terminate_stream_handler(#state{opts=Opts}, StreamID, Reason, StreamState) ->
|
||||
try
|
||||
cowboy_stream:terminate(StreamID, Reason, StreamState)
|
||||
catch Class:Exception ->
|
||||
catch Class:Exception:Stacktrace ->
|
||||
cowboy:log(cowboy_stream:make_error_log(terminate,
|
||||
[StreamID, Reason, StreamState],
|
||||
Class, Exception, erlang:get_stacktrace()), Opts)
|
||||
Class, Exception, Stacktrace), Opts)
|
||||
end.
|
||||
|
||||
%% System callbacks.
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
-module(cowboy_loop).
|
||||
-behaviour(cowboy_sub_protocol).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([upgrade/4]).
|
||||
-export([upgrade/5]).
|
||||
-export([loop/4]).
|
||||
|
@ -81,10 +77,9 @@ call(Req0, Env, Handler, HandlerState0, Message) ->
|
|||
suspend(Req, Env, Handler, HandlerState);
|
||||
{stop, Req, HandlerState} ->
|
||||
terminate(Req, Env, Handler, HandlerState, stop)
|
||||
catch Class:Reason ->
|
||||
StackTrace = erlang:get_stacktrace(),
|
||||
catch Class:Reason:Stacktrace ->
|
||||
cowboy_handler:terminate({crash, Class, Reason}, Req0, HandlerState0, Handler),
|
||||
erlang:raise(Class, Reason, StackTrace)
|
||||
erlang:raise(Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
suspend(Req, Env, Handler, HandlerState) ->
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
|
||||
-module(cowboy_req).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
%% Request.
|
||||
-export([method/1]).
|
||||
-export([version/1]).
|
||||
|
@ -224,10 +220,10 @@ qs(#{qs := Qs}) ->
|
|||
parse_qs(#{qs := Qs}) ->
|
||||
try
|
||||
cow_qs:parse_qs(Qs)
|
||||
catch _:_ ->
|
||||
catch _:_:Stacktrace ->
|
||||
erlang:raise(exit, {request_error, qs,
|
||||
'Malformed query string; application/x-www-form-urlencoded expected.'
|
||||
}, erlang:get_stacktrace())
|
||||
}, Stacktrace)
|
||||
end.
|
||||
|
||||
-spec match_qs(cowboy:fields(), req()) -> map().
|
||||
|
@ -415,10 +411,10 @@ parse_header(Name, Req) ->
|
|||
parse_header(Name, Req, Default) ->
|
||||
try
|
||||
parse_header(Name, Req, Default, parse_header_fun(Name))
|
||||
catch _:_ ->
|
||||
catch _:_:Stacktrace ->
|
||||
erlang:raise(exit, {request_error, {header, Name},
|
||||
'Malformed header. Please consult the relevant specification.'
|
||||
}, erlang:get_stacktrace())
|
||||
}, Stacktrace)
|
||||
end.
|
||||
|
||||
parse_header_fun(<<"accept">>) -> fun cow_http_hd:parse_accept/1;
|
||||
|
@ -546,10 +542,10 @@ read_urlencoded_body(Req0, Opts) ->
|
|||
{ok, Body, Req} ->
|
||||
try
|
||||
{ok, cow_qs:parse_qs(Body), Req}
|
||||
catch _:_ ->
|
||||
catch _:_:Stacktrace ->
|
||||
erlang:raise(exit, {request_error, urlencoded_body,
|
||||
'Malformed body; application/x-www-form-urlencoded expected.'
|
||||
}, erlang:get_stacktrace())
|
||||
}, Stacktrace)
|
||||
end;
|
||||
{more, Body, _} ->
|
||||
Length = maps:get(length, Opts, 64000),
|
||||
|
@ -616,10 +612,10 @@ read_part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) ->
|
|||
%% Ignore epilogue.
|
||||
{done, _} ->
|
||||
{done, Req#{multipart => done}}
|
||||
catch _:_ ->
|
||||
catch _:_:Stacktrace ->
|
||||
erlang:raise(exit, {request_error, {multipart, headers},
|
||||
'Malformed body; multipart expected.'
|
||||
}, erlang:get_stacktrace())
|
||||
}, Stacktrace)
|
||||
end.
|
||||
|
||||
-spec read_part_body(Req)
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
-module(cowboy_rest).
|
||||
-behaviour(cowboy_sub_protocol).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([upgrade/4]).
|
||||
-export([upgrade/5]).
|
||||
|
||||
|
@ -812,8 +808,8 @@ variances(Req, State=#state{content_types_p=CTP,
|
|||
<<"vary">>, [H|Variances5], Req2),
|
||||
resource_exists(Req3, State2)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
variances(Req, State, Variances) ->
|
||||
|
@ -850,8 +846,8 @@ if_match(Req, State, EtagsList) ->
|
|||
%% Etag may be `undefined' which cannot be a member.
|
||||
false -> precondition_failed(Req2, State2)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
if_match_must_not_exist(Req, State) ->
|
||||
|
@ -878,8 +874,8 @@ if_unmodified_since(Req, State, IfUnmodifiedSince) ->
|
|||
true -> precondition_failed(Req2, State2);
|
||||
false -> if_none_match_exists(Req2, State2)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
if_none_match_exists(Req, State) ->
|
||||
|
@ -904,8 +900,8 @@ if_none_match(Req, State, EtagsList) ->
|
|||
false -> method(Req2, State2)
|
||||
end
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
%% Weak Etag comparison: only check the opaque tag.
|
||||
|
@ -947,8 +943,8 @@ if_modified_since(Req, State, IfModifiedSince) ->
|
|||
true -> method(Req2, State2);
|
||||
false -> not_modified(Req2, State2)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
not_modified(Req, State) ->
|
||||
|
@ -958,11 +954,11 @@ not_modified(Req, State) ->
|
|||
try set_resp_expires(Req3, State2) of
|
||||
{Req4, State3} ->
|
||||
respond(Req4, State3, 304)
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State2, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State2, Class, Reason, Stacktrace)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
precondition_failed(Req, State) ->
|
||||
|
@ -1115,8 +1111,8 @@ process_content_type(Req, State=#state{method=Method, exists=Exists}, Fun) ->
|
|||
Exists -> respond(Req3, State2, 303);
|
||||
true -> respond(Req3, State2, 201)
|
||||
end
|
||||
end catch Class:Reason = {case_clause, no_call} ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
end catch Class:Reason = {case_clause, no_call}:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
%% If PUT was used then the resource has been created at the current URL.
|
||||
|
@ -1142,8 +1138,8 @@ set_resp_body_etag(Req, State) ->
|
|||
try set_resp_etag(Req, State) of
|
||||
{Req2, State2} ->
|
||||
set_resp_body_last_modified(Req2, State2)
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
%% Set the Last-Modified header if any for the response provided.
|
||||
|
@ -1159,8 +1155,8 @@ set_resp_body_last_modified(Req, State) ->
|
|||
<<"last-modified">>, LastModifiedBin, Req2),
|
||||
set_resp_body_expires(Req3, State2)
|
||||
end
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
%% Set the Expires header if any for the response provided.
|
||||
|
@ -1168,8 +1164,8 @@ set_resp_body_expires(Req, State) ->
|
|||
try set_resp_expires(Req, State) of
|
||||
{Req2, State2} ->
|
||||
if_range(Req2, State2)
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req, State, Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
%% When both the if-range and range headers are set, we perform
|
||||
|
@ -1254,9 +1250,10 @@ set_ranged_body_auto(Req, State=#state{handler=Handler, content_type_a={_, Callb
|
|||
switch_handler(Switch, Req2, State2);
|
||||
{Body, Req2, State2} ->
|
||||
maybe_set_ranged_body_auto(Req2, State2, Body)
|
||||
end catch Class:{case_clause, no_call} ->
|
||||
end catch Class:{case_clause, no_call}:Stacktrace ->
|
||||
error_terminate(Req, State, Class, {error, {missing_callback, {Handler, Callback, 2}},
|
||||
'A callback specified in content_types_provided/2 is not exported.'})
|
||||
'A callback specified in content_types_provided/2 is not exported.'},
|
||||
Stacktrace)
|
||||
end.
|
||||
|
||||
maybe_set_ranged_body_auto(Req=#{range := {_, Ranges}}, State, Body) ->
|
||||
|
@ -1379,9 +1376,10 @@ set_ranged_body_callback(Req, State=#state{handler=Handler}, Callback) ->
|
|||
true -> send_multipart_ranged_body(Req2, State2, Ranges);
|
||||
false -> set_multipart_ranged_body(Req2, State2, Ranges)
|
||||
end
|
||||
end catch Class:{case_clause, no_call} ->
|
||||
end catch Class:{case_clause, no_call}:Stacktrace ->
|
||||
error_terminate(Req, State, Class, {error, {missing_callback, {Handler, Callback, 2}},
|
||||
'A callback specified in ranges_provided/2 is not exported.'})
|
||||
'A callback specified in ranges_provided/2 is not exported.'},
|
||||
Stacktrace)
|
||||
end.
|
||||
|
||||
set_one_ranged_body(Req0, State, OneRange) ->
|
||||
|
@ -1471,9 +1469,10 @@ set_resp_body(Req, State=#state{handler=Handler, content_type_a={_, Callback}})
|
|||
{Body, Req2, State2} ->
|
||||
Req3 = cowboy_req:set_resp_body(Body, Req2),
|
||||
multiple_choices(Req3, State2)
|
||||
end catch Class:{case_clause, no_call} ->
|
||||
end catch Class:{case_clause, no_call}:Stacktrace ->
|
||||
error_terminate(Req, State, Class, {error, {missing_callback, {Handler, Callback, 2}},
|
||||
'A callback specified in content_types_provided/2 is not exported.'})
|
||||
'A callback specified in content_types_provided/2 is not exported.'},
|
||||
Stacktrace)
|
||||
end.
|
||||
|
||||
multiple_choices(Req, State) ->
|
||||
|
@ -1578,8 +1577,8 @@ call(Req0, State=#state{handler=Handler,
|
|||
no_call;
|
||||
{Result, Req, HandlerState} ->
|
||||
{Result, Req, State#state{handler_state=HandlerState}}
|
||||
catch Class:Reason ->
|
||||
error_terminate(Req0, State, Class, Reason)
|
||||
catch Class:Reason:Stacktrace ->
|
||||
error_terminate(Req0, State, Class, Reason, Stacktrace)
|
||||
end;
|
||||
false ->
|
||||
no_call
|
||||
|
@ -1620,11 +1619,10 @@ switch_handler({switch_handler, Mod}, Req, #state{handler_state=HandlerState}) -
|
|||
switch_handler({switch_handler, Mod, Opts}, Req, #state{handler_state=HandlerState}) ->
|
||||
{Mod, Req, HandlerState, Opts}.
|
||||
|
||||
-spec error_terminate(cowboy_req:req(), #state{}, atom(), any()) -> no_return().
|
||||
error_terminate(Req, #state{handler=Handler, handler_state=HandlerState}, Class, Reason) ->
|
||||
StackTrace = erlang:get_stacktrace(),
|
||||
-spec error_terminate(cowboy_req:req(), #state{}, atom(), any(), any()) -> no_return().
|
||||
error_terminate(Req, #state{handler=Handler, handler_state=HandlerState}, Class, Reason, Stacktrace) ->
|
||||
cowboy_handler:terminate({crash, Class, Reason}, Req, HandlerState, Handler),
|
||||
erlang:raise(Class, Reason, StackTrace).
|
||||
erlang:raise(Class, Reason, Stacktrace).
|
||||
|
||||
terminate(Req, #state{handler=Handler, handler_state=HandlerState}) ->
|
||||
Result = cowboy_handler:terminate(normal, Req, HandlerState, Handler),
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
-module(cowboy_stream_h).
|
||||
-behavior(cowboy_stream).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([init/3]).
|
||||
-export([data/4]).
|
||||
-export([info/3]).
|
||||
|
@ -285,33 +281,16 @@ send_request_body(Pid, Ref, fin, BodyLen, Data) ->
|
|||
|
||||
%% Request process.
|
||||
|
||||
%% 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 Better spec.
|
||||
%% We add the stacktrace to exit exceptions here in order
|
||||
%% to simplify the debugging of errors. The proc_lib library
|
||||
%% already adds the stacktrace to other types of exceptions.
|
||||
-spec request_process(cowboy_req:req(), cowboy_middleware:env(), [module()]) -> ok.
|
||||
request_process(Req, Env, Middlewares) ->
|
||||
OTP = erlang:system_info(otp_release),
|
||||
try
|
||||
execute(Req, Env, Middlewares)
|
||||
catch
|
||||
exit:Reason ->
|
||||
Stacktrace = erlang:get_stacktrace(),
|
||||
erlang:raise(exit, {Reason, Stacktrace}, Stacktrace);
|
||||
%% OTP 19 does not propagate any exception stacktraces,
|
||||
%% we therefore add it for every class of exception.
|
||||
_:Reason when OTP =:= "19" ->
|
||||
Stacktrace = erlang:get_stacktrace(),
|
||||
erlang:raise(exit, {Reason, Stacktrace}, Stacktrace);
|
||||
%% @todo I don't think this clause is necessary.
|
||||
Class:Reason ->
|
||||
erlang:raise(Class, Reason, erlang:get_stacktrace())
|
||||
exit:Reason:Stacktrace ->
|
||||
erlang:raise(exit, {Reason, Stacktrace}, Stacktrace)
|
||||
end.
|
||||
|
||||
execute(_, _, []) ->
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
-module(cowboy_websocket).
|
||||
-behaviour(cowboy_sub_protocol).
|
||||
|
||||
-ifdef(OTP_RELEASE).
|
||||
-compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
|
||||
-endif.
|
||||
|
||||
-export([is_upgrade_request/1]).
|
||||
-export([upgrade/4]).
|
||||
-export([upgrade/5]).
|
||||
|
@ -513,11 +509,10 @@ handler_call(State=#state{handler=Handler}, HandlerState,
|
|||
end;
|
||||
{stop, HandlerState2} ->
|
||||
websocket_close(State, HandlerState2, stop)
|
||||
catch Class:Reason ->
|
||||
StackTrace = erlang:get_stacktrace(),
|
||||
catch Class:Reason:Stacktrace ->
|
||||
websocket_send_close(State, {crash, Class, Reason}),
|
||||
handler_terminate(State, HandlerState, {crash, Class, Reason}),
|
||||
erlang:raise(Class, Reason, StackTrace)
|
||||
erlang:raise(Class, Reason, Stacktrace)
|
||||
end.
|
||||
|
||||
-spec handler_call_result(#state{}, any(), parse_state(), fun(), commands()) -> no_return().
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue