Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang application undef error (exited: {bad_return,)

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: <0.106.0>
    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: [<0.105.0>]
    messages: [{'EXIT',<0.107.0>,normal}]
    links: [<0.105.0>,<0.7.0>]
    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: <0.75.0>
    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: [<0.74.0>]
    messages: [{'EXIT',<0.76.0>,normal}]
    links: [<0.74.0>,<0.7.0>]
    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).
like image 552
mattk Avatar asked Dec 12 '22 16:12

mattk


1 Answers

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 in egs_patch_app:start/2. The atom EXIT is the tag of a notification message sent when a process has exited, or the result of an expression like catch 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 is cowboy: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 least egs and egs_patch). You'll quite possibly need to clear your deps/ 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 a case 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 as 1/x instead of 1/X.

To learn more about Erlang's error handling mechanisms, read the docs.

like image 143
Martin Törnwall Avatar answered Dec 22 '22 11:12

Martin Törnwall