Related
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}]}]}}
Alright, what am I doing wrong here. I'm trying the simple example of embedded YAWs from http://yaws.hyber.org/embed.yaws but with an appmod. I've added the my_app.erl file and compiled it. It works if not in embedded YAWs so I think it is specific to embedded.
-module(ybed).
-compile(export_all).
start() ->
{ok, spawn(?MODULE, run, [])}.
run() ->
Id = "embedded",
GconfList = [{ebin_dir, ["/Users/someuser/yawsembedded/ebin"]}],
Docroot = "/Users/someuser/yawstest",
SconfList = [{port, 8888},
{listen, {0,0,0,0}},
{docroot, Docroot},
{appmods, [{"/", my_app}]}
],
{ok, SCList, GC, ChildSpecs} =
yaws_api:embedded_start_conf(Docroot, SconfList, GconfList),
[supervisor:start_child(ybed_sup, Ch) || Ch <- ChildSpecs],
yaws_api:setconf(GC, SCList),
{ok, self()}.
Getting this Error:
ERROR erlang code threw an uncaught exception:
File: appmod:0
Class: error
Exception: undef
Req: {http_request,'GET',{abs_path,"/demo"},{1,1}}
Stack: [{my_app,out,
[{arg,#Port<0.2721>,
{{127,0,0,1},63720},
{headers,"keep-alive",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"0.0.0.0:8888",undefined,undefined,undefined,undefined,
undefined,undefined,undefined,
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:40.0) Gecko/20100101 Firefox/40.0",
undefined,[],undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
[{http_header,0,"Dnt",undefined,"1"},
{http_header,10,'Accept-Encoding',undefined,
"gzip, deflate"},
{http_header,11,'Accept-Language',undefined,"null"}]},
{http_request,'GET',{abs_path,"/demo"},{1,1}},
{http_request,'GET',{abs_path,"/demo"},{1,1}},
undefined,"/demo",undefined,undefined,
"/Users/someuser/yawstest","/",
"/Users/someuser/yawstest/demo",undefined,undefined,
<0.63.0>,[],"/","/",undefined}],
[]},
{yaws_server,deliver_dyn_part,8,
[{file,"yaws_server.erl"},{line,2818}]},
{yaws_server,aloop,4,[{file,"yaws_server.erl"},{line,1232}]},
{yaws_server,acceptor0,2,[{file,"yaws_server.erl"},{line,1068}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]
The stack trace shows that your my_app:out/1 function is getting called, but you're getting an undef exception. This is occurring because the runtime can't find the my_app:out/1 function, which means either it can't find the module or the module exists but does not export an out/1 function. For example, I was able to duplicate the error using the example code by not providing a my_app module.
First, make sure your my_app.erl file exports an out/1 function. Here's a trivial one that just returns a 405 error for all requests:
-module(my_app).
-export([out/1]).
out(_Arg) ->
{status, 405}.
Compile your my_app.erl file and put the compiled my_app.beam file either in a load path already known to the Erlang runtime, or in a directory you add to the load path. In your code it appears you're trying the latter approach, since you're specifically adding an ebin_dir with this Yaws global configuration directive:
GconfList = [{ebin_dir, ["/Users/someuser/yawsembedded/ebin"]}],
You need to verify that the /Users/someuser/yawsembedded/ebin directory exists, and that the compiled my_app.beam file is located there.
I am trying to compile a new module for ejabberd in erlang.I am following this tutorial:http://jasonrowe.com/2011/12/30/ejabberd-offline-messages
I am trying to compile this code:
%% name of module must match file name
-module(mod_http_offline).
-author("Earl The Squirrel").
%% Every ejabberd module implements the gen_mod behavior
%% The gen_mod behavior requires two functions: start/2 and stop/1
-behaviour(gen_mod).
%% public methods for this module
-export([start/2, stop/1, create_message/3]).
%% included for writing to ejabberd log file
-include("ejabberd.hrl").
%% ejabberd functions for JID manipulation called jlib.
-include("jlib.hrl").
start(_Host, _Opt) ->
post_offline_message("testFrom", "testTo", "testBody"),
?INFO_MSG("mod_http_offline loading", []),
ejabberd_hooks:add(offline_message_hook, _Host, ?MODULE, create_message, 50).
stop (_Host) ->
?INFO_MSG("stopping mod_http_offline", []),
ejabberd_hooks:delete(offline_message_hook, _Host, ?MODULE, create_message, 50).
create_message(_From, _To, Packet) ->
Type = xml:get_tag_attr_s("type", Packet),
FromS = xml:get_tag_attr_s("from", Packet),
ToS = xml:get_tag_attr_s("to", Packet),
Body = xml:get_path_s(Packet, [{elem, "body"}, cdata]),
if (Type == "chat") ->
post_offline_message(FromS, ToS, Body)
end.
post_offline_message(From, To, Body) ->
?INFO_MSG("Posting From ~p To ~p Body ~p~n",[From, To, Body]),
?INFO_MSG("post request sent (not really yet)", []).
I have added jlib.hrl,ejabberd.hrl to my folder.But when I try to compile this code I am getting following errors:
jlib.hrl:22: can't find include lib "p1_xml/include/xml.hrl"
mod_http_offline.erl:21: undefined macro 'INFO_MSG/2'
mod_http_offline.erl:27: undefined macro 'INFO_MSG/2'
mod_http_offline.erl:44: undefined macro 'INFO_MSG/2'
jlib.hrl:426: record xmlel undefined
jlib.hrl:466: type xmlel() undefined
mod_http_offline.erl:11: function start/2 undefined
mod_http_offline.erl:11: function stop/1 undefined
mod_http_offline.erl:38: function post_offline_message/3 undefined
mod_http_offline.erl:8: Warning: behaviour gen_mod undefined
How can I resolve this ?
My Ejabberd version:2.1.11
The jlib.hrl file in ejabberd repository contains -include("ns.hrl"). (line 21) and -include_lib("p1_xml/include/xml.hrl"). line 22. The include_lib means that it will search the file in library path. You could modify this and add the necessary files in your directory (maybe a simple solution to test?) but I think that the clean way is to add tour file to the ejabberd application and use rebar to compile it.
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.
I have following module
-module(bhavcopy_downloader).
-export([download/2]).
download(From, SaveTo) ->
{ok, {{Status, _}, _, Body}} = lhttpc:request(From, "GET", [], infinity),
case Status of
200 -> file:write(SaveTo, Body),
true;
_ -> false
end.
And following tests for the above code
file_download_test_() ->
{foreach,
fun() ->
meck:new(lhttpc)
meck:new(file, [unstick])
end,
fun(_) ->
meck:unload(file),
meck:unload(lhttpc)
end,
{"saves the file at specified location",
fun() ->
meck:expect(lhttpc, request, 4, {ok, {{200, "OK"}, [], <<"response">>}}),
meck:expect(file, write_file, fun(Path, Data) ->
?assertEqual(Path, "~/Downloads/data-downloader/test.html"),
?assertEqual(Data, <<"response">>)
end),
?assertEqual(true, bhavcopy_downloader:download("http://google.com", "~/Downloads/data-downloader/test.html")),
?assert(meck:validate(file))
end}]
}.
When I run the tests I get following error (only part of the error pasted below for brevity). Looking at the error below, I am kind of feeling that file module is not being mocked (or the mock of file module being overridden when I set the other mock using meck:new(lhttpc). What could be going wrong here?
=ERROR REPORT==== 16-Feb-2013::20:17:24 ===
** Generic server file_meck terminating
** Last message in was {'EXIT',<0.110.0>,
{compile_forms,
{error,
[{[],
[{none,compile,
{crash,beam_asm,
{undef,
[{file,get_cwd,[],[]},
{filename,absname,1,
[{file,"filename.erl"},{line,67}]},
{compile,beam_asm,1,
[{file,"compile.erl"},{line,1245}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,273}]},
{compile,fold_comp,3,
[{file,"compile.erl"},{line,291}]},
{compile,internal_comp,4,
[{file,"compile.erl"},{line,275}]},
{compile,'-do_compile/2-anonymous-0-',2,
[{file,"compile.erl"},{line,152}]}]}}}]}],
[{"src/lhttpc_types.hrl",
[{31,erl_lint,{new_builtin_type,{boolean,0}}},
{31,erl_lint,{renamed_type,bool,boolean}}]}]}}}
This is a catch 22 in Meck, caused by the fact that Meck uses the Erlang compiler, which in turns uses the file module. When Meck tries recompile the file module it needs the file module (through the compiler) and thus crashes.
As of this moment, Meck doesn't handle mocking the file module. Your best alternative is to wrap the file module calls in another module and mock this module instead.
(It is theoretically possible to fix this in Meck by using the internals of the compiler and the code server instead, for example erlang:load_module/2, however this is quite tricky and needs to be designed and tested well)