diff options
Diffstat (limited to 'test/cowboy_error_h.erl')
-rw-r--r-- | test/cowboy_error_h.erl | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/test/cowboy_error_h.erl b/test/cowboy_error_h.erl index fe79645..b4ae78f 100644 --- a/test/cowboy_error_h.erl +++ b/test/cowboy_error_h.erl @@ -30,11 +30,12 @@ %% Ignore crashes from Pid occuring in M:F/A. ignore(M, F, A) -> - gen_event:call(error_logger, ?MODULE, {expect, self(), M, F, A}). + gen_event:call(error_logger, ?MODULE, {expect, {self(), M, F, A}}). %% gen_event. init(_) -> + spawn(fun() -> error_logger:tty(false) end), {ok, []}. %% Ignore supervisor and progress reports. @@ -50,9 +51,41 @@ handle_event({error_report, _, {_, crash_report, {error_info, {error, gone, _}}|_]|_]}}, State) -> {ok, State}; -%% Ignore emulator reports, they are a duplicate of what Ranch gives us. -handle_event({error, _, {emulator, _, _}}, State) -> - {ok, State}; +%% Ignore emulator reports that are a duplicate of what Ranch gives us. +%% +%% The emulator always sends strings for errors, which makes it very +%% difficult to extract the information we need, hence the regexps. +handle_event(Event = {error, GL, {emulator, _, Msg}}, State) + when node(GL) =:= node() -> + Result = re:run(Msg, + "Error in process ([^\s]+).+? with exit value: " + ".+?{stacktrace,\\[{([^,]+),([^,]+),(.+)", + [{capture, all_but_first, list}]), + case Result of + nomatch -> + write_event(Event), + {ok, State}; + {match, [PidStr, MStr, FStr, Rest]} -> + A = case Rest of + "[]" ++ _ -> + 0; + "[" ++ Rest2 -> + count_args(Rest2, 1, 0); + _ -> + {match, [AStr]} = re:run(Rest, "([^,]+).+", + [{capture, all_but_first, list}]), + list_to_integer(AStr) + end, + Crash = {list_to_pid(PidStr), list_to_existing_atom(MStr), + list_to_existing_atom(FStr), A}, + case lists:member(Crash, State) of + true -> + {ok, lists:delete(Crash, State)}; + false -> + write_event(Event), + {ok, State} + end + end; handle_event(Event = {error, GL, {_, "Ranch listener" ++ _, [_, _, Pid, {[_, _, {stacktrace, [{M, F, A, _}|_]}|_], _}]}}, @@ -72,8 +105,8 @@ handle_event(Event = {_, GL, _}, State) when node(GL) =:= node() -> handle_event(_, State) -> {ok, State}. -handle_call({expect, Pid, M, F, A}, State) -> - {ok, ok, [{Pid, M, F, A}|State]}; +handle_call({expect, Crash}, State) -> + {ok, ok, [Crash, Crash|State]}; handle_call(_, State) -> {ok, {error, bad_query}, State}. @@ -81,12 +114,32 @@ handle_info(_, State) -> {ok, State}. terminate(_, _) -> + spawn(fun() -> error_logger:tty(true) end), ok. code_change(_, State, _) -> {ok, State}. +%% Internal. + write_event(Event) -> error_logger_tty_h:write_event( {erlang:universaltime(), Event}, io). + +count_args("]" ++ _, N, 0) -> + N; +count_args("]" ++ Tail, N, Levels) -> + count_args(Tail, N, Levels - 1); +count_args("[" ++ Tail, N, Levels) -> + count_args(Tail, N, Levels + 1); +count_args("}" ++ Tail, N, Levels) -> + count_args(Tail, N, Levels - 1); +count_args("{" ++ Tail, N, Levels) -> + count_args(Tail, N, Levels + 1); +count_args("," ++ Tail, N, Levels = 0) -> + count_args(Tail, N + 1, Levels); +count_args("," ++ Tail, N, Levels) -> + count_args(Tail, N, Levels); +count_args([_|Tail], N, Levels) -> + count_args(Tail, N, Levels). |