Force verbose error report - erlang

Once running my test I faced this:
=ERROR REPORT==== 29-Jul-2016::01:34:22 ===
** Generic server <0.141.0> terminating
** Last message in was {send_req,
{{url,
***************,
*****************,443,
undefined,undefined,"/api",https,hostname},
[{"X-API-Version","0.5"},
{"Accept","*/*"}],
post,<<>>,
[{is_ssl,true},
{ssl_option,
[{certfile,
<<"/Users/slava/src/api/cert_dev.pem">>},
{password,"nil"}]}],
15000}}
** Reason for termination ==
** {{badmatch,false},
[{ibrowse_lib,get_value,2,
[{file,"/Users/slava/Documents/src/api/deps/ibrowse/src/ibrowse_lib.erl"},
{line,184}]},
{ibrowse_http_client,check_ssl_options,2,
{gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,629}]},
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,661}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]}
Then I ran the same test and it failed with small error message. Very uninformative.
Can't figure out what actually forced this verbose report.
Usual one:
1) test get vehicle data by vin
test/adapter_test.exs:14
match (=) failed
code: %HTTPotion.Response{} = Adapter.request(:get, 'vehicles', vin: #vin)
rhs: %HTTPotion.ErrorResponse{message: "closed"}
stacktrace:
test/remoto_adapter_test.exs:15: (test)

Related

Unexpected ':infinity' argument appears in call to ':odbc.sql_query/2' in Elixir project

Summary
I'm trying to query an SQL database in Elixir, via ODBC.
When running :odbc.sql_query/2 with two arguments (see code example below), a third :infinity argument appears. This third, unknown argument causes a run-time exception:
C:\code\elixir_odbc>mix run
starting
13:44:37.212 [info] Application elixir_odbc exited: exited in: MyMix.start(:normal, [])
** (EXIT) an exception was raised:
** (FunctionClauseError) no function clause matching in :odbc.sql_query/3
(odbc) odbc.erl:186: :odbc.sql_query(#PID<0.101.0>, "select count(*) from 'my-catalog'.my_table", :infinity)
(elixir_odbc) lib/elixir_odbc.ex:23: ElixirOdbc.get_rec_count/0
(elixir_odbc) lib/my_mix.ex:7: MyMix.start/2
(kernel) application_master.erl:273: :application_master.start_it_old/4
** (Mix) Could not start application elixir_odbc: exited in: MyMix.start(:normal, [])
** (EXIT) an exception was raised:
** (FunctionClauseError) no function clause matching in :odbc.sql_query/3
(odbc) odbc.erl:186: :odbc.sql_query(#PID<0.101.0>, "select count(*) from 'my-catalog'.my_table", :infinity)
(elixir_odbc) lib/elixir_odbc.ex:23: ElixirOdbc.get_rec_count/0
(elixir_odbc) lib/my_mix.ex:7: MyMix.start/2
(kernel) application_master.erl:273: :application_master.start_it_old/4
Where is this mysterious :infinity argument coming from?
Details
In mix.exs, I'm including :odbc from Erlang/OTP:
def application do
[
mod: {MyMix, []},
extra_applications: [:logger, :odbc]
]
end
In /lib/elixir_odbc.ex, I have the the following code:
defmodule ElixirOdbc do
def get_rec_count do
:odbc.start()
case :odbc.connect(
'dsn=my_dsn',
[]
) do
{:ok, conn} ->
case :odbc.sql_query(conn, "select count(*) from 'my-catalog'.my_table") do
{:selected, _colNames, [{count}]} -> IO.puts("Number of rows: #{count}")
{:error, err} -> {:error, err}
end
{:error, err} ->
{:error, err}
end
:odbc.stop()
end
end
Also in /lib/my_mix.ex, I have the following mod, which implements the Application protocol:
defmodule MyMix do
use Application
def start(_type, _args) do
IO.puts("starting")
ElixirOdbc.get_rec_count()
Task.start(fn ->
:timer.sleep(1000)
IO.puts("done sleeping")
end)
end
end
The application compiles without any errors or warnings.
I get the same error when manually calling ElixirOdbc.get_rec_count from within the iex REPL, having started the application with iex -S mix.
If I run odbc:sql_query/2 manually directly from the Erlang REPL (Eshell), then everything works fine and I get the expected data from the database.
I found the issue.
In my case, there are several database catalogs, so the call to :odbc.sql_query was liked this:
:odbc.sql_query(conn, "select count(*) from 'my-catalog'.my_table")
Notice that the string which is the second parameter is double-quoted, wherein the database catalog name ('my-catalog') is single-quoted. That was the cause of this issue.
Apparently, the nested quotation needed to be the other way around.
After changing the call to this:
:odbc.sql_query(conn, 'select count(*) from "my-catalog".my_table')
Everything works as expected:
c:\code\elixir_odbc>mix run
starting
Number of rows: 70737
14:41:49.304 [info] Application odbc exited: :stopped
I discovered the cause of this issue by going through by Eshell history and looking very carefully at the manual call I did (which was working), and discovered that I had reverset the quotations.

YAWS responds with errors under light load. "Unhandled reply fr. do_recv() {error,econnaborted}"

Hello fellow Erlangers :)
Just another Erlang enthusiast playing with the language here. I have a very simple YAWS app module which works fine when accessed by single clients. However, if I try to span multiple clients to simulate light traffic, those clients start receiving errors. Any idea what can be causing it?
Code spawning the clients:
-module(concurrent).
-export([measure/0, get/0]).
get() ->
Result = httpc:request("http://localhost:8080/blah"),
io:format("Result: ~p.\n", [Result]).
get_spawner(0) -> io:format("Done.\n");
get_spawner(Times) ->
spawn(concurrent, get, []),
get_spawner(Times - 1).
measure() ->
io:fwrite("Starting inets...\n"),
inets:start(),
io:fwrite("Done\n"),
io:fwrite("Creating blah...\n"),
httpc:request(put, { "http://localhost:8080/blah", [], "", "" }, [], []),
io:fwrite("Done\n"),
get_spawner(9),
io:fwrite("Stopping inets...\n"),
inets:stop(),
io:fwrite("Done\n"),
init:stop().
I observed that it all works just fine for 8 concurrent clients, but when I span 9 or more clients, they start receiving the following message back from the server:
=ERROR REPORT==== 24-Jan-2017::12:30:04 ===
** Generic server httpc_manager terminating
** Last message in was {request,
{request,undefined,<0.74.0>,0,http,
{"localhost",8080},
"/blah",[],get,
{http_request_h,undefined,"keep-alive",
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,"localhost:8080",
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,[],undefined,undefined,undefined,
undefined,"0",undefined,undefined,
undefined,undefined,undefined,undefined,[]},
{[],[]},
{http_options,"HTTP/1.1",infinity,true,
{essl,[]},
undefined,false,infinity,false},
"http://localhost:8080/blah",[],none,[],
1485261004189,undefined,undefined,false}}
** When Server state == {state,[],httpc_manager__handler_db,
{cookie_db,undefined,8209},
httpc_manager__session_db,httpc_manager,
{options,
{undefined,[]},
{undefined,[]},
0,2,5,120000,2,disabled,false,inet,default,
default,[]}}
** Reason for termination ==
** {'EXIT',
{shutdown,
{gen_server,call,
[httpc_handler_sup,
{start_child,
[<0.61.0>,
{request,#Ref<0.0.6.64>,<0.74.0>,0,http,
{"localhost",8080},
"/blah",[],get,
{http_request_h,undefined,"keep-alive",undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,"localhost:8080",undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,[],undefined,
undefined,undefined,undefined,"0",undefined,
undefined,undefined,undefined,undefined,
undefined,[]},
{[],[]},
{http_options,"HTTP/1.1",infinity,true,
{essl,[]},
undefined,false,infinity,false},
"http://localhost:8080/blah",[],none,[],
1485261004189,undefined,undefined,false},
{options,
{undefined,[]},
{undefined,[]},
0,2,5,120000,2,disabled,false,inet,default,default,
[]},
httpc_manager]},
infinity]}}}
=ERROR REPORT==== 24-Jan-2017::12:30:04 ===
Error in process <0.74.0> with exit value:
{{case_clause,
{undefined,
{error,
{'EXIT',
{shutdown,
{gen_server,call,
[httpc_handler_sup,
{start_child,
[<0.61.0>,
{request,#Ref<0.0.6.64>,<0.74.0>,0,http,
{"localhost",8080},
"/blah",[],get,
{http_request_h,undefined,"keep-alive",
undefined,undefined,undefined,
undefined,undefined,undefined,
undefined,undefined,undefined,
undefined,undefined,undefined,
undefined,undefined,"localhost:8080",
undefined,undefined,undefined,
undefined,undefined,undefined,
undefined,undefined,undefined,[],
undefined,undefined,undefined,
undefined,"0",undefined,undefined,
undefined,undefined,undefined,
undefined,[]},
{[],[]},
{http_options,"HTTP/1.1",infinity,true,
{essl,[]},
undefined,false,infinity,false},
"http://localhost:8080/blah",[],none,[],
1485261004189,undefined,undefined,false},
{options,
{undefined,[]},
{undefined,[]},
0,2,5,120000,2,disabled,false,inet,default,
default,[]},
httpc_manager]},
infinity]}}}}}},
[{httpc,handle_request,9,[{file,"httpc.erl"},{line,574}]},
{concurrent,get,0,
[{file,
"c:/Users/piotr_justyna/Documents/rets/performance_tests/concurrent.erl"},
{line,5}]}]}
On the server side I am getting this:
=ERROR REPORT==== 24-Jan-2017::12:28:55 ===
Unhandled reply fr. do_recv() {error,econnaborted}
I'm sure it's something straightforward, just can't figure out what it is. Is it the number of concurrent connections that causes it? Can you help shed more light on this?
Regards,
Piotr
Your code spawns a number of httpc:request/1 calls, but then immediately afterwards it stops inets:
...
get_spawner(9),
io:fwrite("Stopping inets...\n"),
inets:stop(),
...
Because inets is shut down, requests that are still in progress are getting shut down prematurely, as you can see in the error report:
** Reason for termination ==
** {'EXIT',
{shutdown,
{gen_server,call,
[httpc_handler_sup,
You need to make the parent of all the spawned requests wait for those requests to finish before calling inets:stop/0. One way to do that would be to pass the parent pid to each spawned child and once httpc:request/1 returns, have the child send a message to the parent. The parent would spawn all N children, then sit in a loop waiting to receive N completion messages from the children, and only after receiving all completion messages would it call inets:stop/0.
The reason it works for 8 requests but not 9 is due to a race condition around the lack of waiting prior to calling inets:stop/0. The default size of the Yaws pool of request handling acceptor processes happens to be 8. When your code sends 8 requests, the pool handles it quickly enough to beat your code's call to inets:stop/0, but with 9, there's a slight delay as one acceptor handles two requests, and that slight timing change is enough to allow your inets:stop/0 call to clobber one or more of your client processes. You can modify the Yaws acceptor pool size via the acceptor_pool_size configuration variable.
If you're serious about load testing you might consider using an industrial-strength solution like tsung instead of rolling your own.

Specflow bypasses subsequent scenarios after a failure

All scenarios do what they are supposed to but, until now, I only had 1.
Now that I have a second scenario, the following problem arises.
If the scenario 1 fails an assertion, the subsequent scenarios are skipped.
See below the skipped scenarios.
Setup: ConfigFileTransformation (thread #0)
Scenario: Shows telephone numbers on the header in ShowContactInformation
(target: BrowserBrowserStack_Win8_Chrome_52) -> Succeeded on thread #0
Scenario: Shows telephone numbers on the contact sidebar box in
ShowContactInformation (target: BrowserBrowserStack_Win8_Chrome_52)
-> Failed on thread #0
[ERROR] 2 assertions failed.
Restore: ConfigFileTransformation (thread #0)
Scenario: Shows telephone numbers on the header in ShowContactInformation
(target: BrowserBrowserStack_Win8_Firefox_42)
-> Skipped on thread #-1
Scenario: Shows telephone numbers on the contact sidebar box in
ShowContactInformation
(target: BrowserBrowserStack_Win8_Firefox_42)
-> Skipped on thread #-1
Result: 1 failed
Total: 4
Succeeded: 1
Ignored: 0
Pending: 0
Skipped: 2 <--- **** Other scenarios must be executed regardless of anything else.
Failed: 1
How do I prevent specflow from skipping subsequent scenarios?
Updated the Execution element of the test profile to:
<Execution retryFor="None" stopAfterFailures="0" testThreadCount="1" testSchedulingMode="Sequential" />
The key thing seems to be stopAfterFailures="0".

can I trap exit(self(), kill)?

when i read an artical from learnyousomeerlang.com,I got a question.
http://learnyousomeerlang.com/errors-and-processes
It says that:
Exception source: exit(self(), kill)
Untrapped Result: ** exception exit: killed
Trapped Result: ** exception exit: killed
Oops, look at that. It seems like this one is actually impossible to trap. Let's check something.
but it does not comply with what I test with the code blow:
-module(trapexit).
-compile(export_all).
self_kill_exit()->
process_flag(trap_exit,true),
Pid=spawn_link(fun()->timer:sleep(3000),exit(self(),kill) end),
receive
{_A,Pid,_B}->io:format("subinmain:~p output:~p~n",[Pid,{_A,Pid,_B}])
end.
oupput is:
**4> trapexit:self_kill_exit().
subinmain:<0.36.0> output:{'EXIT',<0.36.0>,killed}**
and does not comply with Trapped Result: ** exception exit: killed said before . which is right???
The call to self in the body of the function passed as an argument to spawn_link doesn't return the process calling spawn_link. It's being evaluated in the newly spawned process and as a result it will return its pid. Make a following change.
-module(trapexit).
-compile(export_all).
self_kill_exit()->
process_flag(trap_exit,true),
Self=self(),
Pid=spawn_link(fun()->timer:sleep(3000),exit(Self,kill) end),
receive
{_A,Pid,_B}->io:format("subinmain:~p output:~p~n",[Pid,{_A,Pid,_B}])
end.
Now it should work as expected.
10> c(trapexit).
{ok,trapexit}
11> trapexit:self_kill_exit().
** exception exit: killed
The book is right. Trapping exit(self(), kill) is not possible.

Erlang runtime error

I'm working on an erlang program and getting a strange runtime error. Any idea why? Thanks!
The errors are (after compiling the program successfully):
8> PID = spawn(planner,start,[]).
** exception error: no match of right hand side value <0.65.0>
9>
This is the program:
-module(planner).
-export([start/0]).
start() ->
loop([],[]).
loop(ContactsList,EventsList) ->
receive
{contact, Last, First, Number} ->
loop([{Last,First,Number}|ContactsList],EventsList);
{event, Date, Time, What} ->
loop([{Date,Time,What}|ContactsList],EventsList);
print_contacts ->
NewList=lists:sort(ContactsList),
lists:foreach(fun(Elem)->io:format("~p~n", [Elem]) end, NewList),
loop(ContactsList,EventsList);
print_events ->
NewList=lists:sort(EventsList),
lists:foreach(fun(Elem)->io:format("~p~n", [Elem]) end, NewList),
loop(ContactsList,EventsList);
exit ->
io:format("Exiting.~n");
_ ->
io:format("Dude, I don't even know what you're talking about.~n"),
loop(ContactsList,EventsList)
end.
The variable PID is probably set to something else but <0.65.0> from an earlier line you entered in the shell:
5> PID = spawn(...).
<0.42.0>
8> PID = spawn(...).
** exception error: no match of right hand side value <0.65.0>
This effectively makes the line which generates the error something like
8> <0.42.0> = <0.65.0>.
which will result in a "no match" error.
More obvious illustration of the issue:
1> X = 1.
1
2> X = 2.
** exception error: no match of right hand side value 2
As to solving your issue: You probably want to run f(PID) to have the shell forget just the PID variable, or even f() to have the shell forget ALL variables.

Resources