Erlang application undef error (exited: {bad_return,)-Collection of common programming errors
I am trying to run a custom application but get multiple errors. I believe the main egs app gets an error because it calls the egs patch app which has an undefined type. I cant figure out how to get this working I have tried recompiling the code many times in regards to others with a similar problem but nothing seems to work. The cowboy start listener remains undefined.
This is the error I receive.
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid:
registered_name: []
exception exit: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},
{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},
{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: []
messages: [{'EXIT',,normal}]
links: [,]
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 27
reductions: 124
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs_patch
exited: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid:
registered_name: []
exception exit: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: []
messages: [{'EXIT',,normal}]
links: [,]
dictionary: []
trap_exit: true
status: running
heap_size: 987
stack_size: 27
reductions: 185
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs
exited: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
Here are the files from which the errors originate.
egs_patch_app.erl
-module(egs_patch_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, PatchPorts} = application:get_env(patch_ports),
start_listeners(PatchPorts),
egs_patch_sup:start_link().
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_listeners([inet:ip_port()]) -> ok.
start_listeners([]) ->
ok;
start_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({patch, Port}, 10,
cowboy_tcp_transport, [{port, Port}],
egs_patch_protocol, []),
start_listeners(Tail).
egs_app.erl
-module(egs_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-include("/home/mattk/Desktop/egs-master/apps/egs/include/records.hrl").
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
-define(SSL_OPTIONS, [{certfile, "priv/ssl/servercert.pem"},
{keyfile, "priv/ssl/serverkey.pem"}, {password, "alpha"}]).
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, Pid} = egs_sup:start_link(),
application:set_env(egs_patch, patch_ports, egs_conf:read(patch_ports)),
application:start(egs_patch),
start_login_listeners(egs_conf:read(login_ports)),
{_ServerIP, GamePort} = egs_conf:read(game_server),
{ok, _GamePid} = cowboy:start_listener({game, GamePort}, 10,
cowboy_ssl_transport, [{port, GamePort}] ++ ?SSL_OPTIONS,
egs_game_protocol, []),
{ok, Pid}.
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_login_listeners([inet:ip_port()]) -> ok.
start_login_listeners([]) ->
ok;
start_login_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({login, Port}, 10,
cowboy_ssl_transport, [{port, Port}] ++ ?SSL_OPTIONS,
egs_login_protocol, []),
start_login_listeners(Tail).
-
Here’s our hint:
..... {{egs_patch_app,start,[normal,[]]}, {'EXIT', {undef, [{cowboy,start_listener, .....
The tuple
{egs_patch_app,start,[normal,[]]}
tells us that the error occurred inegs_patch_app:start/2
. The atomEXIT
is the tag of a notification message sent when a process has exited, or the result of an expression likecatch error(someerror)
. Now we get to the interesting part.undef
means an attempt was made to call an undefined function. A function is undefined if its Name/Arity doesn’t match any known function. In this case, the undefined function iscowboy:start_listener()
.Once again, the problem is that Cowboy has evolved while egs has not. Major changes in the Cowboy API have made the two incompatible. Since the last change in egs was about a year ago (assuming you’re using essen’s branch), you could try reverting to an older Cowboy tag by changing the corresponding
rebar.config
line to something like this:{cowboy, ".*", {git, "git://github.com/extend/cowboy.git", {tag, "0.6.0"}}
Notice how
"HEAD"
changed to{tag, "0.6.0"}
. The Cowboy reference may have to be changed in several applications (at leastegs
andegs_patch
). You’ll quite possibly need to clear yourdeps/
first.Erlang error messages can be difficult to parse, but as a general rule of thumb, you should be on the lookout for a few atoms:
case_clause
, meaning no clause in acase
expression matched.function_clause
, meaning no function clause matched the arguments.undef
, as noted above, meaning a call to an external (not local to module) function couldn’t be resolved.badarg
, which is Erlang’s “illegal argument” exception.badarith
, a sneaky bastard that sometimes shows up when you mistype a variable name as an atom in an arithmetic expression, such as1/x
instead of1/X
.
To learn more about Erlang’s error handling mechanisms, read the docs.