Question

I'm building a simple erlang application and very new to the enviornment, so I'm having trouble making sense of some errors I'm getting. I'm not sure what the root of my problem is here, so if there's anything relevant that I don't post, please let me know:

Source for module I'm running:

  -module(basilisk_server).
  -author("Oak").

  -export([start_link/2,start/0,start/1,start/2, stop/1]).
  -behaviour(application).
  -record(options,{
    port = 6890,
    server_opts = []
  }).
  -define(LocalIP,"192.168.64.128").
  start()->
    start([]).
  start(Args)->
    #options{port = Port, server_opts = ServerOpts}  = parse_args(Args),
    spawn(
      fun() ->
        start_link(Port, ServerOpts),
        receive after infinity -> ok end
      end)
  .
  start(_StartType, Args) ->
    start(Args).

  parse_args(Args) -> parse_args(Args, #options{}).
  parse_args([], Opts) -> Opts;
  parse_args([Head | Rest], Opts) ->
    NewOpts =
      case catch list_to_integer(Head) of
        Port when is_integer(Port) ->
          Opts#options{port = Port};
        _Else ->
          case Head of
            "framed" ->
              Opts#options{server_opts = [{framed, true} | Opts#options.server_opts]};
            "" ->
              Opts;
            _Else ->
              erlang:error({bad_arg, Head})
          end
      end,
    parse_args(Rest, NewOpts)
  .
  stop(_State) ->
    ok.

  start_link(Port, ServerOpts) ->
    io:format("Starting server on port ~p with args: ~p~n",[Port,ServerOpts]),

    Services =
      [
        {"AuthenticationService",authenticationService_thrift},
        {"UserRegistrationService",userRegistrationService_thrift}
      ]
    ,
    {ok, _} = thrift_socket_server:start([
      {ip, ?LocalIP},

      {port, Port},
      {name, ?MODULE},
      {service, Services},
      {handler,[
        {"error_handler",  thrift_error_handler},
        {"AuthenticationService",authentication_service},
        {"UserRegistrationService",user_registration_service}
      ]},
      {socket_opts, [{recv_timeout, infinity}]}
    ]++
    ServerOpts).

I run application:start(basilisk_server). and get these messages in this order:

   {error,{bad_return,{{basilisk_server,start,[normal,[]]},
                      <0.38.0>}}}

  =INFO REPORT==== 29-Jul-2014::03:11:06 ===
      application: basilisk_server
      exited: {bad_return,{{basilisk_server,start,[normal,[]]},<0.38.0>}}
      type: temporary

  =ERROR REPORT==== 29-Jul-2014::03:11:06 ===
  Error in process <0.38.0> with exit value: {terminated,[{io,format,
 [<0.36.0>,"Starting server on port ~p with args: ~p~n",[6890,[]]],[]},
 {basilisk_server,start_link,2,[{file,"src/basilisk_server.erl"},{line,55}]}, 
 {basilisk_server,'-start/1-fun-0-',2,[{file,"src/basilisk_serve... 

The main problem I'm having is identifying the actual source of the error. I was under the impression that io:format was the problem for a short while, but I believe that was a "red herring" and that bad_result is the root of my problem. I ran the program in an almost identical state and it was working, and suddenly started getting this error. I rolled back most of the changes and it hasn't stopped. I also tried rebooting, in case it was a problem with a background process.

Was it helpful?

Solution

You're using application:start, which expects your module to adhere to the application behaviour.

That is: it will call foo:start/2, to tell you that your application is starting. You are expected to return {ok, Pid}. This is documented in the "Applications" chapter of the OTP Design Principles.

However, your start function immediately calls spawn, and uses the result of that. Since spawn returns Pid, rather than {ok, Pid}, application:start is complaining about a mismatch in the expected result.

Which is why you're seeing bad_return:

{error,{bad_return,{{basilisk_server,start,[normal,[]]},
                  <0.38.0>}}}

This is telling you that you got an error, of type bad_return. It happened when calling basilisk_server:start(normal, []), and it got a return value of <0.38.0> (a pid).

Oh, and the other error is because you used start_link, which means that your two processes are linked. When one dies, the other will be killed. This is what you're seeing with the terminated. In this case, it happened to be killed in the middle of io:format; it might make it further before being killed in other runs.

Moreover, an application is assumed to start a root supervisor (this is what the returned pid is for).

At this point, you don't need the application behaviour. In fact, I'm not convinced that you need most of your code at all. Just call thrift_socket_server:start and be done with it. It'll continue to run in the background.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top