How to set breakpoint inside with part of try-with expression? - f#

try
raise (InvalidOperationException())
with e ->
printfn "WTF"
I want debugger to stop at line printfn "WTF", but this does not happen. Neither in Visual Studio, nor in LinqPad.
What am I doing wrong?

When debugger in IDE is not attaching as you wish, you can call debugger break in the code to be sure it will be catched.
with e ->
System.Diagnostics.Debugger.Break()
printfn "WTF"

Related

Why does F# interactive console not consider "assert (2=3)" as wrong?

I send this line to F# interactive console in Visual Studio
assert (2=3)
To my surprise, the console does not report errors, but
 
val it : unit = ()
Similarly, if I run
printf ("hello!")
assert (2=3)
printf ("hello2")
on an REPL, I got "hellohello2" without any error messages.
How could I make the F# interactive tell me 2=3 is wrong?
Under the cover, the assert keyword translates to a method call to the Debug.Assert method from the .NET library (see the method documentaiton). This has a conditional compilation attribute [Conditional("DEBUG")], meaning that the call is only included if the symbol DEBUG is defined.
By default, this is not the case in F# Interactive. You can do that by adding --define:DEBUG to the command line parameters for fsi.exe. This will be somewhere in the options of your editor, depending on what you are using. For example, in Visual Studio, you need something like this:
EDIT: How to do something like this if you do not want to modify the command line parameters? This really depends on what exactly behaviour you want. The default behaviour of assert is that it shows a message box where you can either terminate the program or ignore the error. You could do that using:
open System.Windows.Forms
let ensure msg b =
let res =
MessageBox.Show("Assertion failed: " + msg +
"\n\nDo you want to terminate the exection? Press 'Yes' " +
"to stop or 'No' to ignore the error.", "Assertion failed",
MessageBoxButtons.YesNo)
if res = DialogResult.Yes then exit 42
ensure "Mathematics is broken" (2=3)

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}]}]}}

Debugger break location with F# exception handling

I came across this recently and wanted to check if there was something I was misunderstanding about F# exceptions. I am using Visual Studio 2012. Given the following F# code:
[<EntryPoint>]
let main argv =
try
raise (System.AccessViolationException("foo"))
printfn "Should not get here"
raise (System.AccessViolationException("foo"))
printfn "Should not get here either"
with | :? System.FormatException -> printfn "Should not get here"
This will raise and AccessViolationException which should not be caught by the with statement because the with only handles System.FormatException. I expected the debugger to be at the first raise when the exception occurs, but it is actually at the end of the with:
Now the problem is I can't see where the exception was raised from, also I can't see any information about the exception such as stacktrace. I don't think that I want to change the exception settings for individual exceptions because I would want to know the location of any unhandled exception (similar to C# or VB.NET) not when thrown.
If this is just the way that it is, then that is OK, but I just wanted to ask since I am not very familiar with F# and I wanted to make sure that I wasn't missing something. I had a look online and did not find anything about this.
Unless you want to modify your exception settings to break when that exception type is thrown (or a category of exceptions in the exception settings) then you need to make sure that your code takes care of unhandled exceptions however is most appropriate for your code.
try
raise (System.AccessViolationException("foo"))
with
| :? System.FormatException -> printfn "Should not get here"
| _ as ex ->
#if DEBUG
System.Diagnostics.Debugger.Break();
#else
printfn "Unhandled exception ('%s'): '%s'" (ex.GetType().Name) ex.Message
#endif

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.

Avoid NZEC error in Erlang in SPOJ

I've written code in Erlang, and I get the correct answer on my machine. But when I submit it on SPOJ it gives an NZEC (non zero exit code) error. I have used built-in functions like halt() and init:stop(), and their specification clearly says that they are used to avoid non-zero exit code error. But still I get the same error. How can I solve this problem?
EDIT The code as required by a comment:
-module(factorial).
-export([main/0]).
main() ->
{ok, [No_of_cases]} = io:fread("", "~d"),
loop(No_of_cases).
loop(0) ->
%init:stop();
halt(1);
loop(No_of_cases) ->
{ok, [Number]} = io:fread("", "~d"),
ResultFactorial = find_factorial(Number,1),
io:format("~p~n",[ResultFactorial]),
loop(No_of_cases-1).
find_factorial(0,Product) ->
Product;
find_factorial(Number,Product) ->
find_factorial(Number-1,Product*Number).
I got the answer. The trick is that your module name always has to be tested and the entry point should be function main . For example, after compilation it should be run as tested:main().

Resources