Erlang Dependency Not Started Error - erlang

I am trying to run a start script but I end up with the following error.
{"init terminating in do_boot",{{case_clause,{error,{not_started,ranch}}},[{egs,ensure_started,1,[{file,"src/egs.erl"},{line,84}]},{egs,start,0,[{file,"src/egs.erl"},{line,49}]},{init,start_it,1,[]},{init,start_em,1,[]}]}}
I can compile the entire folder with multiple dependencies and this is the only one with an error. I use 'make' to compile and it is supposed to be 'make run' to run but that isn't working. Is that why I am getting this error? Any ideas on how to fix it would be greatly appreciated.
The file where I get the error from is below.
-module(egs).
-export([start/0, stop/0, global/1, warp/4, warp/5]). %% API.
%% Player and account-related types.
-type gid() :: 0..16#ffffffff.
-type lid() :: 0..1023 | 16#ffff.
-type character_slot() :: 0..3.
-export_type([gid/0, lid/0, character_slot/0]).
%% Location related types.
-type uniid() :: 21 | 26..254 | 16#ffffffff.
-type questid() :: 0..16#ffffffff. %% #todo What's the real max?
-type zoneid() :: 0..16#ffff. %% #todo What's the real max?
-type mapid() :: 0..9999.
-type entryid() :: 0..16#ffff. %% #todo What's the real max?
-type area() :: {questid(), zoneid(), mapid()}. %% #todo Probably remove later.
-type position() :: {X::float(), Y::float(), Z::float(), Dir::float()}.
-export_type([uniid/0, questid/0, zoneid/0, mapid/0, entryid/0,
area/0, position/0]).
%% API.
-spec start() -> ok.
start() ->
ensure_started(crypto),
ensure_started(public_key),
ensure_started(ssl),
ensure_started(cowboy),
ensure_started(ranch),
application:start(egs).
-spec stop() -> ok.
stop() ->
Res = application:stop(egs),
ok = application:stop(cowboy),
ok = application:stop(ranch),
ok = application:stop(ssl),
ok = application:stop(public_key),
ok = application:stop(crypto),
Res.
%% #doc Send a global message.
-spec global(string()) -> ok.
global(Message) when length(Message) > 511 ->
io:format("global: message too long~n");
global(Message) ->
egs_users:broadcast_all({egs, notice, top, Message}).
%% #doc Warp all players to a new map.
-spec warp(questid(), zoneid(), mapid(), entryid()) -> ok.
warp(QuestID, ZoneID, MapID, EntryID) ->
egs_users:broadcast_all({egs, warp, QuestID, ZoneID, MapID, EntryID}).
%% #doc Warp one player to a new map.
-spec warp(gid(), questid(), zoneid(), mapid(), entryid()) -> ok.
warp(GID, QuestID, ZoneID, MapID, EntryID) ->
egs_users:broadcast({egs, warp, QuestID, ZoneID, MapID, EntryID}, [GID]).
%% Internal.
-spec ensure_started(module()) -> ok.
ensure_started(App) ->
case application:start(App) of
ok -> ok;
{error, {already_started, App}} -> ok
end.

The order of application startup is important. In particular, cowboy depends on ranch and crypto. Also, public_key depends on crypto and must be started before ssl. The correct start order is:
ok = application:start(crypto),
ok = application:start(public_key),
ok = application:start(ssl),
ok = application:start(ranch),
ok = application:start(cowboy),
ok = application:start(egs).
For applications built with Rebar, the startup dependencies are listed in [app]/src/[app].app.src. See the LYSE chapter.
The reason it didn't work out of the box is probably that EGS depends on Cowboy's master branch, which quite recently introduced Ranch as a dependency.

Related

How to generate document for Ejabberd custom modules?

I have created some custom modules I need to create documentation for all my custom module So any help?
You can use edoc - http://erlang.org/doc/apps/edoc/chapter.html. Eg:
test_edoc.erl
-module(test_edoc).
-export([run/1]).
%% -------------------------------------------------------------------
%% #doc
%% Some description
%% #end
%% -------------------------------------------------------------------
-spec run(N :: integer()) -> Result :: integer() | error.
run(N) when is_integer(N) -> N + 1;
run(_) -> error.
Then in Erlang shell:
1> edoc:files(["test_edoc.erl"], [{dir, doc}]).
ok
Then in current folder where you run edoc:files/2 should be generated the doc folder, so, go to the doc folder and open in browser test_edoc.html

Erlang exited with reason - undef (with string:find/2 func)

trying to use function string:find/2but every time getting the error
CRASH REPORT Process <0.779.0> with 0 neighbours exited with reason: {{undef,[{string,find,[[<<208,162,51,32,208,190,208,177,209,137,46,44,32,84,51,32,116,111,116,97,108,44>>],[<<208,186,209,128,208,190,208,178>>]],[]},{proxy_layer_cli_handle_req,do_execute_keysearch,4,[{file,\"/opt/proxy_layer/_build/test/lib/proxy_layer/src/proxy_layer_cli_handle_req.erl\"},{line,222}]},{proxy_layer_cli_handle_req,keysearch,3,[{file,\"/opt/proxy_layer/_build/test/lib/proxy_layer/src/proxy_layer_cli_handle_req.erl\"},{line,...}]},...]},...}
when i use it in terminal - everything is okay
1> string:find(<<208,162,51,32,208,190,208,177,209,137,46,44,32,84,51,32,116,111,116,97,108,44>>,<<208,186,209,128,208,190,208,178>>).
1> nomatch
I'm using Erlang 20.1
here is the code which I use:
do_execute_keysearch([First|Rest], PriceList, Keyword, Acc) ->
Id = utils:get_value(<<"Id">>, First),
case utils:get_value(<<"Keywords">>, First) of
<<>> -> do_execute_keysearch(Rest, PriceList, Keyword, Acc);
undefined -> do_execute_keysearch(Rest, PriceList, Keyword, Acc);
Keys ->
case string:find(Keys, Keyword) of
nomatch ->
do_execute_keysearch(Rest, PriceList, Keyword, Acc);
_ ->
Price = find_price_by_service_id(PriceList, Id),
NewAcc = [lists:append(Price, First) | Acc],
do_execute_keysearch(Rest, PriceList, Keyword, NewAcc)
end
end;
UPDATE:
Issue fixed after changing Erlang version in docker container. (Changed to Erlang 20.1)
Don’t know why there are some modules undefined in Erlang 19
So the problem solved now
string:find/2 was added to Erlang in version 20 which is why you were getting an undef error in Erlang 19. The solution is to upgrade to Erlang 20 (which you've already done).
Look at the error more carefully. Or rather, try to reproduce it. Which of these looks more like your error?
1> catch lists:nonexist(<<1>>, <<2>>).
{'EXIT',{undef,[{lists,nonexist,[<<1>>,<<2>>],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]},
{shell,exprs,7,[{file,"shell.erl"},{line,687}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
2> catch lists:nonexist([<<1>>], [<<2>>]).
{'EXIT',{undef,[{lists,nonexist,[[<<1>>],[<<2>>]],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]},
{shell,exprs,7,[{file,"shell.erl"},{line,687}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}

[Cowboy-Erlang]: Error when pin-pointing to localhost:8080 using provided cowboy example web_server

I am trying out a cowboy example provided by this github repository:
https://github.com/ninenines/cowboy/tree/master/examples/web_server
I build the release successfully using erlang.mk and run the following command, which opens the Erlang shell in my linux terminal:
$ ./_rel/web_server_example/bin/web_server_example console
But when I then open http://localhost:8080 in my web-browser, I get the following error report:
=ERROR REPORT==== 26-Nov-2014::14:33:48 === Error in process <0.166.0> on node 'web_server_example#127.0.0.1' with exit value:
{function_clause,[{cowboy_req,ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<3
bytes>>,'HTTP/1.1',{{127,0,0,1},57150},<<9 bytes>>,undefined,8080,<<1
byte>>,undefined,<<0 bytes>>,undefined,undefined,[{<<4 bytes>>,<<14
bytes>>},{<<10 bytes>>,<<10 bytes>>},{<<13 bytes>>,<<9 bytes>>},{<<6
bytes>>,<<74 bytes>>},{<<10 bytes>>,<<104 bytes>>},{<<15 bytes>>,<<19
bytes>>},{<<15 bytes>>,<<35 bytes>>}],[{<<10 bytes>>,[<<10
bytes>>]}],undefined,[],waiting,<<0 bytes>>,undefined...
=ERROR REPORT==== 26-Nov-2014::14:33:48 === Ranch listener http had connection process started with cowboy_protocol:start_link/4 at
<0.166.0> exit with reason:
{function_clause,[{cowboy_req,ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<"GET">>,'HTTP/1.1',{{127,0,0,1},57150},<<"localhost">>,undefined,8080,<<"/">>,undefined,<<>>,undefined,undefined,[{<<"host">>,<<"localhost:8080">>},{<<"connection">>,<<"keep-alive">>},{<<"cache-control">>,<<"max-age=0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8">>},{<<"user-agent">>,<<"Mozilla/5.0
(X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/39.0.2171.65 Safari/537.36">>},{<<"accept-encoding">>,<<"gzip,
deflate,
sdch">>},{<<"accept-language">>,<<"sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4">>}],[{<<"connection">>,[<<"keep-alive">>]}],undefined,[],waiting,<<>>,undefined,false,done,[],<<>>,undefined}},204],[{file,"src/cowboy_req.erl"},{line,1009}]},{cowboy_protocol,next_request,3,[{file,"src/cowboy_protocol.erl"},{line,454}]}]}
This is "src/cowboy_protocol.erl" around line 454:
-spec next_request(cowboy_req:req(), #state{}, any()) -> ok.
next_request(Req, State=#state{req_keepalive=Keepalive, timeout=Timeout},
HandlerRes) ->
cowboy_req:ensure_response(Req, 204),
%% If we are going to close the connection,
%% we do not want to attempt to skip the body.
case cowboy_req:get(connection, Req) of
close ->
terminate(State);
_ ->
%% Skip the body if it is reasonably sized. Close otherwise.
Buffer = case cowboy_req:body(Req) of
{ok, _, Req2} -> cowboy_req:get(buffer, Req2);
_ -> close
end,
%% Flush the resp_sent message before moving on.
if HandlerRes =:= ok, Buffer =/= close ->
receive {cowboy_req, resp_sent} -> ok after 0 -> ok end,
?MODULE:parse_request(Buffer,
State#state{req_keepalive=Keepalive + 1,
until=until(Timeout)}, 0);
true ->
terminate(State)
end
end.
And the webb_server_app.erl file:
%% Feel free to use, reuse and abuse the code in this file.
%% #private
-module(web_server_app).
-behaviour(application).
%% API.
-export([start/2]).
-export([stop/1]).
%% API.
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/[...]", cowboy_static, {priv_dir, web_server, "", [
{mimetypes, cow_mimetypes, all},
{dir_handler, directory_handler}
]}}
]}
]),
{ok, _} = cowboy:start_http(http, 100, [{port, 8080}], [
{env, [{dispatch, Dispatch}]},
{middlewares, [cowboy_router, directory_lister, cowboy_handler]}
]),
web_server_sup:start_link().
stop(_State) ->
ok.
Does anyone have any suggestion as to what is exactly causing this problem, and how to solve it? Thanks.
EDIT:
I can confirm that the fault was in the Erlang OTP version R16B02 in my case. Changing to the latest Erlang release (17.3), as well as resolving missing file dependencies that arose during the configuration stage (with the solutions in the following link):
https://sites.google.com/site/comptekkia/erlang/how-to-install-erlang-on-ubuntu-10-10
Solved the problem(s). The web_server example runs without error now.
The error says function clause, so the arguments to cowboy_req:ensure_response/2 must be wrong. And indeed they are, because first argument is {ok, Request} instead of Request. You have to trace back, which function called next_request/3 with bad argument, because it clearly should be called without ok.
Probably somewhere at the end, you will find something like:
Req = some_function(...)
And you will need to change it to:
{ok, Req} = some_function(...)
Good luck and happy bug hunting :D
UPDATE: I just cloned the repo and it works fine for me. I got the directory listing, so it is not bug in cowboy, but somewhere in user code.

External function call Erlang

I'm trying to call a function (from an external module) in erlang. both beam files are located in the same directory.
-module(drop2).
-export([fall_velocity/1]).
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
Then I'm calling
-module(ask).
-export([term/0]).
term() ->
Input = io:read("Enter {x,distance} ? >>"),
Term = element(2,Input),
drop2:fall_velocity(Term).
it gives the following error.I tested individual modules for errors. it is compiling with out any errors or warning.
Eshell V5.10.2 (abort with ^G)
1> ask:term().
Enter {x,distance} ? >>{test,10}.
** exception error: an error occurred when evaluating an arithmetic expression
in function drop2:fall_velocity/1 (drop2.erl, line 3)
Not sure why it is throwing arithmetic expression error .
You could read the documentation to figure out that the result is {ok, Term}. You could try the io:read/1 function in the console, then you'd see following:
1> io:read("Enter > ").
Enter > {test, 42}.
{ok,{test,42}}
2>
That means that you need to deconstruct the result of io:read/1 differently, for example like this:
-module(ask).
-export([term/0]).
term() ->
{ok, {_, Distance}} = io:read("Enter {x, distance} > "),
drop2:fall_velocity(Distance).

Having Dialyzer support Custom Behaviours

I am using Dialyzer with a few custom behaviors, the problem is that when I do that, Dialyzer gives me this error:
src/max.erl:3: Callback info about the gen_strategy behaviour is not available
One thing I can't figure out is how to create that callback info. I would like to add this information to my behaviour, so I can get that much more testing out of Dialyzer.
Starting with R15B, The Erlang/OTP compiler was upgraded so that it now handles a new module attribute, named -callback.
Example:
-callback init(Args :: term()) ->
{ok, State :: term()} | {ok, State :: term(), timeout() | hibernate} |
{stop, Reason :: term()} | ignore.
More about that here and here

Resources