Changed the messages sent to the backends to include metadata and separated formatting from the backend. Added documentation, fixed tests, and removed some unused code.
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad return value: bleh",[Pid])),
?assertEqual(Expected,lists:flatten(Msg))
end
},
{"bad return value with string",
fun()->
Pid=whereis(crash),
crash(bad_return_string),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad return value: {tuple,{tuple,\"string\"}}",[Pid])),
?assertEqual(Expected,lists:flatten(Msg))
end
},
{"bad return value uncaught throw",
fun()->
Pid=whereis(crash),
crash(throw),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad return value: a_ball",[Pid])),
?assertEqual(Expected,lists:flatten(Msg))
end
},
{"case clause",
fun()->
Pid=whereis(crash),
crash(case_clause),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no case clause matching {} in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"case clause string",
fun()->
Pid=whereis(crash),
crash(case_clause_string),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no case clause matching \"crash\" in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"function clause",
fun()->
Pid=whereis(crash),
crash(function_clause),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no function clause matching crash:function({})",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"if clause",
fun()->
Pid=whereis(crash),
crash(if_clause),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no true branch found while evaluating if expression in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"try clause",
fun()->
Pid=whereis(crash),
crash(try_clause),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no try clause matching [] in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"undefined function",
fun()->
Pid=whereis(crash),
crash(undef),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: call to undefined function crash:booger/0 from crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad math",
fun()->
Pid=whereis(crash),
crash(badarith),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad arithmetic expression in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad match",
fun()->
Pid=whereis(crash),
crash(badmatch),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no match of right hand value {} in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad arity",
fun()->
Pid=whereis(crash),
crash(badarity),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: fun called with wrong arity of 1 instead of 3 in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad arg1",
fun()->
Pid=whereis(crash),
crash(badarg1),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad argument in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad arg2",
fun()->
Pid=whereis(crash),
crash(badarg2),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad argument in call to erlang:iolist_to_binary([\"foo\",bar]) in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"bad record",
fun()->
Pid=whereis(crash),
crash(badrecord),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad record state in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
},
{"noproc",
fun()->
Pid=whereis(crash),
crash(noproc),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no such process or port in call to gen_event:call(foo, bar, baz)",[Pid])),
?assertEqual(Expected,lists:flatten(Msg))
end
},
{"badfun",
fun()->
Pid=whereis(crash),
crash(badfun),
{_,_,Msg}=pop(),
Expected=lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad function booger in crash:handle_call/3",[Pid])),
test_body(Expected,lists:flatten(Msg))
end
}
TestBody("bad return value",bad_return,"gen_server crash terminated with reason: bad return value: bleh"),
TestBody("bad return value with string",bad_return_string,"gen_server crash terminated with reason: bad return value: {tuple,{tuple,\"string\"}}"),
TestBody("bad return uncaught throw",throw,"gen_server crash terminated with reason: bad return value: a_ball"),
TestBody("case clause",case_clause,"gen_server crash terminated with reason: no case clause matching {} in crash:handle_call/3"),
TestBody("case clause string",case_clause_string,"gen_server crash terminated with reason: no case clause matching \"crash\" in crash:handle_call/3"),
TestBody("function clause",function_clause,"gen_server crash terminated with reason: no function clause matching crash:function({})"),
TestBody("if clause",if_clause,"gen_server crash terminated with reason: no true branch found while evaluating if expression in crash:handle_call/3"),
TestBody("try clause",try_clause,"gen_server crash terminated with reason: no try clause matching [] in crash:handle_call/3"),
TestBody("undefined function",undef,"gen_server crash terminated with reason: call to undefined function crash:booger/0 from crash:handle_call/3"),
TestBody("bad math",badarith,"gen_server crash terminated with reason: bad arithmetic expression in crash:handle_call/3"),
TestBody("bad match",badmatch,"gen_server crash terminated with reason: no match of right hand value {} in crash:handle_call/3"),
TestBody("bad arity",badarity,"gen_server crash terminated with reason: fun called with wrong arity of 1 instead of 3 in crash:handle_call/3"),
TestBody("bad arg1",badarg1,"gen_server crash terminated with reason: bad argument in crash:handle_call/3"),
TestBody("bad arg2",badarg2,"gen_server crash terminated with reason: bad argument in call to erlang:iolist_to_binary([\"foo\",bar]) in crash:handle_call/3"),
TestBody("bad record",badrecord,"gen_server crash terminated with reason: bad record state in crash:handle_call/3"),
TestBody("noproc",noproc,"gen_server crash terminated with reason: no such process or port in call to gen_event:call(foo, bar, baz)"),
TestBody("badfun",badfun,"gen_server crash terminated with reason: bad function booger in crash:handle_call/3")
Expected=lists:flatten(io_lib:format("[error] ~w Supervisor steve had child mini_steve started with a:b(c) at bleh exit with reason fired in context france",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w Supervisor steve had child mini_steve started with a:b(c) at bleh exit with reason no function clause matching crash:handle_info(foo) in context france",[self()])),
?assertEqual("Supervisor steve had child mini_steve started with a:b(c) at bleh exit with reason no function clause matching crash:handle_info(foo) in context france",lists:flatten(Msg))
Expected=lists:flatten(io_lib:format("[error] ~w Supervisor steve had child at module mini_steve at bleh exit with reason fired in context france",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: maximum number of file descriptors exhausted, check ulimit -n",[self(),self()])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: maximum number of file descriptors exhausted, check ulimit -n",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded",[self(),self()])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded",[self(),self()])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ports exceeded",[self(),self()])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ports exceeded",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: tried to create an atom larger than 255, or maximum atom count exceeded",[self(),self()])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: tried to create an atom larger than 255, or maximum atom count exceeded",[self()])),
Expected=lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ETS tables exceeded",[self(),test])),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ETS tables exceeded",[test])),
Expected=lists:flatten(io_lib:format("[error] ~pCRASH REPORT Process ~p with 0 neighbours crashed with reason: no function clause matching special_process:foo(bar)",
[Pid,Pid])),
{_,_,Msg,_Metadata}=pop(),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~p with 0 neighbours crashed with reason: no function clause matching special_process:foo(bar)",
Expected=lists:flatten(io_lib:format("[error] ~pCRASH REPORT Process ~p with 0 neighbours crashed with reason: no case clause matching wtf in special_process:loop/0",
[Pid,Pid])),
{_,_,Msg,_Metadata}=pop(),
Expected=lists:flatten(io_lib:format("CRASH REPORT Process ~p with 0 neighbours crashed with reason: no case clause matching wtf in special_process:loop/0",