In Haskell (ghc) Control.Exception, the difference between try and catch - exception

all!
I'm a bit confused.
Is there inconsistency between document and code in library Control.Exception?
The document say that the function 'catch' use the function 'mask' on a handler function
but a function try doesn't use a function mask.
But the code say that the function 'try' use the function 'catch'.
I think that
if the function 'catch' use the function 'mask'
and the function 'try' use the function 'catch',
then the function 'try' use the function 'mask'.
In Control.Exception of ghc base-package, the document say
"There's an implied mask around every exception handler in a call to one of the catch family of functions. This is because that is what you want most of the time - it eliminates a common race condition in starting an exception handler, because there may be no exception handler on the stack to handle another exception if one arrives immediately. If asynchronous exceptions are masked on entering the handler, though, we have time to install a new exception handler before being interrupted. If this weren't the default, one would have to write something like
mask $ \restore ->
catch (restore (...))
(\e -> handler)
If you need to unblock asynchronous exceptions again in the exception handler, restore can be used there too.
Note that try and friends do not have a similar default, because there is no exception handler in this case. Don't use try for recovering from an asynchronous exception. ".
But, the code say
"try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))"

What this comment means is that if you use try like this:
e <- try act
case e of
Left e -> handleError e
Right r -> doSomething r
there won't be a mask around the term handleError e, unlike in the case of catch act handleError.

Related

Is it possible to capture TypeInitializationException when setting a value?

When using the SQL type provider when the app.config file does not supply a valid connection, a TypeInitializationException is thrown. I would like to capture this exception and return a more helpful message (such as "Your app.config file is missing"), but I'm having trouble. I've tried the following:
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
type SqlConnection = Microsoft.FSharp.Data.TypeProviders.SqlDataConnection<ConnectionStringName = "DBConnectionString">
let DB1 =
try SqlConnection.GetDataContext()
with | ex -> failwith "Exception 1"
When I try-catch this, the exception that I catch is actually a NullReferenceException, and my "Exception 1" then gets wrapped in a TypeInitializationException.
I can do this:
let getDB2 () =
try DB1
with | ex -> failwith "Exception 2"
...in which ex is the TypeInitializationException, and then it throws Exception 2 as I want, but when I try:
let DB3 =
try getDB2()
with | ex -> failwith "Exception 3"
...then it gets wrapped in another TypeInitializationException, which strangely has wrapped Exception 1 instead of Exception 3, seemingly bypassing the try-with block in DB3. (I should note that I'm calling all these things from C# when I'm doing my testing, in case that matters.)
Is it possible to avoid having the generic TypeInitializationException be the outer exception when trying to access the DB, without exposing it as a function? And why is the TypeInitializationException not caught like other exceptions?
--- Addendum ---
After fooling around a little more, I discovered that this behaviour occurs when setting ANY value. For example, this:
let x : int =
try failwith "Exception A"
with | ex -> failwith "Exception B"
...results in a TypeInitializationException wrapped around an Exception B.
Is this an F# thing, and is there any way to capture this exception during the setting of the value?
Your DB1 is not a function, but a value. It gets evaluated when the module is loaded, which in .NET happens on the first attempt to access anything from the module. That's why your exception gets thrown as soon as you try to do anything at all.
Further, in .NET, any exception thrown during static initialization of a class (and F# modules are compiled as .NET classes) gets wrapped in a TypeInitializationException (I am not very clear on the rationale behind this).
If you want DB1 to be a function, and to be evaluated only when called, give it a parameter. If you don't have any meaningful parameters to give, make it unit (denoted in F# by an empty pair of parentheses):
let DB1 () =
try SqlConnection.GetDataContext()
with | ex -> failwith "Exception 1"
Your DB1 is a disposable resource and as such, you really should not be creating during module initialization anyway, but rather either return it.
let createDB1 () = new SqlConnection.GetDataContext()
and dispose of it at another appropriate place. Or (my personal preference, as you are less likely to forget the dispose) wrap hide the DB1 completely and rather just inject it into a function
let usingDB1 f =
use db = new SqlConnection.GetDataContext()
f db
let myFunc db = // do something meaningful here
usingDB1 myFunc

AllegroServe Exception Handling

How can I avoid getting an error when passing as argument to the function do-http-request an invalid host.
Is there any way that I can catch the error like the Java's exception-handling mechanism ?
Sure, CL has a very nice condition system. One easy option would be wrapping the call to do-http-request in ignore-errors, which returns nil (and the condition as a second value) if an error condition was signalled in the wrapped code. You could then check for nil afterwards.
If you want something more like exception handling in Java, just use handler-case and add an appropriate error clause (I don't have AllegroServe installed, but I suppose you get a socket-error for providing a wrong URL – just change that part if I misread):
(handler-case
(do-http-request …)
(socket-error ()
…))
If you need finally-like functionality, use unwind-protect:
(unwind-protect
(handler-case
(do-http-request …)
(socket-error (condition) ; bind the signalled condition
…) ; code to run when a socket-error was signalled
(:no-error (value) ; bind the returned value
…)) ; code to run when no condition was signalled
…) ; cleanup code (finally)
You can even get more fancy, and e.g. use handler-bind to handle the condition stack upwards by invoking a restart somewhere down the stack, without unwinding it. For example, if do-http-request provided a restart to try again with another URL, you could handle your error condition by invoking that restart with a new URL to retry. I just mention this for the sake of completeness – it would be overkill for your use case, but being able to resume (possibly expensive) computations easily can be a rather convenient feature.

What is the point of finally in a try catch/except finally statement

I have used try-catch/except-finally variants in many languages for years, today someone asked me what is the point of finally and I couldn't answer.
Basically why would you put a statement in finally instead of just putting it after the whole try-catch block? Or in other words is there a difference between the following blocks of code:
try{ //a}
catch {//b}
finally {//c}
try{//a}
catch{//b}
//c
EDIT:
PEOPLE, I know what finally does, I have been using it for ages, but my question is in the above example putting //c in finally seems redundant, doesn't it?
The purpose of a finally block is to ensure that code gets run in three circumstances which would not very cleanly be handled using "catch" blocks alone:
If code within the try block exits via fallthrough or return
If code within a catch block either rethrows the caught exception, or--accidentally or intentionally--ends up throwing a new one.
If the code within the try block encounters an exception for which the try has no catch.
One could copy the finally code before every return or throw, and wrap catch blocks within their own try/catch to allow for the possibility of an accidental exception occurring, but it's far easier to forgo all that and simply use a finally block.
BTW, one thing I wish language designers would include would be an exception argument to the finally block, to deal with the case where one needs to clean up after an exception but still wants it to percolate up the call stack (e.g. one could wrap the code for a constructor in such a construct, and Dispose the object under construction if the constructor was going to exit with an exception).
Finally block is executed even if an exception thrown in the try block. Therefore, for instance if you opened a stream before, you may want to close that stream either an exception is thrown or not. Finally block is useful for such an issue.
finally is a syntactic sugar to allow DRY principle in try-catch pattern. Exception is usually thrown if the library code has not enough information to handle some state and wants the client code to solve it. If you don't have library-client code separation, you can handle everything by if instead of try.
Let's see a standard situation without finally:
void myFunction() {
var r = allocateResources();
r.doSomething();
if(somethingBadHappens) {
freeResources(r);
throw new Exception(CODE42);
}
r.doSomethingMore();
freeResources(r);
}
In the snippet above, you repeat freeResources(): this can be multiple statements which you need to repeat. This smells and finally block is the solution for clean code:
void myFunction() {
var r = allocateResources();
try {
r.doSomething();
if(somethingBadHappens) throw new Exception(CODE42);
r.doSomethingMore();
}
finally {
freeResources(r);
}
happyFunction();
}
Let's realize three levels of abstraction:
A1 is the library code providing allocateResources() function
A2 is our code providing myFunction, consuming A1
A3 is some client code consuming myFunction in try-catch block:
function A3code() {
try {
myFunction();
doSomething();
}
catch(Exception e) {
// no hanging resources here
Console.WriteLine(e);
}
}
Now let's see what can happen:
if allocateResources() throws in A1, we don't know how to handle it in A2 (A2 code can be run in Console-free environment), so we delagate the situation to A3 without adding any further code. If Exception is thrown here, the finally block is not executed, since finally is bound to try which was not entered.
if somethingBadHappens in try block, the stack unwinds to A3 where the situation is handled BUT before it finally block is executed, so we don't need to repeat it if no exceptions happen.
before finally we can add catch block and try to resolve some potential exceptions from A1 which may appear in calling r.doSomething methods. Usually we want to handle exceptions as soon as possible to make the client code (A3) more comfortable for client coders.
happyFunction() is executed only if nothing throws in myFunction() (inside or outside of try block).
As #supercat points out, the finally block is executed also if try block exits via return. I suggest you avoid this bad habit and have only one return in every function (maybe some early exists at the very beginning of functions). The reasons for single-return functions are:
The code is more readable: you look at the end and see WHAT the function returns. In multiple returns you must find all return occurences, inspect all the ifs, think about when the ifs are satisfied and only then you know what the function returns.
The code can be optimized by compilers, see copy elision.
The reason for multiple returns is avoiding many nested ifs, but there are other techniques to solve it. Exceptions are exception in this rule.
Learn by example
let v = 0;
function f() {
try {
v = 1;
return 2;
} finally {
v = 3;
return 4;
}
v = 5;
return 6;
}
const r = f();
console.log(r, v);
following prints "3, 4"
Finally make sure your code is executed even if you get an exception.
The finally block is useful for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception
http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx

Erlang error handling philosophy - case vs throw

I'm writing a REST service in Erlang and need to verify the received data before passing it to other internal functions for further processing; in order to do that, I'm currently using nested case expressions like this:
case all_args_defined(Args) of
true ->
ActionSuccess = action(Args),
case ActionSuccess of
{ok, _} -> ...;
{fail, reason} -> {fail, reason}
end,
_ ->
{fail, "args not defined"}
end,
...
I realize this is kind of ugly, but this way I can provide detailed error messages. Additionally, I don't think the usual make it crash philosophy is applicable here - I don't want my REST service to crash and be restarted every time somebody throws invalid arguments at it.
However, I'm considering abandoning all those cases in favor of an umbrella try/catch block catching any badmatch errors - would this work?
fun() ->
true = all_args_defined(Args),
{ok, _} = action(Args).
%% somewhere else
catch fun().
Since what you want to achieve is error reporting, you should structure the thing around the execution of actions and reporting of the result. Perhaps something like this:
execute(Action, Args) ->
try
check_args(Args),
Result = action(Action, Args),
send_result(Result)
catch
throw:{fail, Reason} ->
report_error(Reason);
ExceptionClass:Term ->
%% catch-all for all other unexpected exceptions
Trace = erlang:get_stacktrace(),
report_error({crash, ExceptionClass, Term, Trace})
end.
%% all of these throw {fail, Reason} if they detect something fishy
%% and otherwise they return some value as result (or just crash)
action(foo, [X1, X2]) -> ...;
action(foo, Args) -> throw({fail, {bad_arity, foo, 2, Args}});
action(...) -> ...
%% this handles the formatting of all possible errors
report_error({bad_arity, Action, Arity, Args}) ->
send_error(io_lib:format("wrong number of arguments for ~w: "
"expected ~w, but got ~w",
[Action, Arity, length(Args)]));
report_error(...) -> ...;
report_error({crash, Class, Term, Trace}) ->
send_error(io_lib:format("internal error: "
"~w:~w~nstacktrace:~n~p~n",
[Class, Term, Trace])).
I've had this problem while developing an application that create users.
I first come with a solution like this:
insert() ->
try
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert()
catch
throw:Error1 ->
handle_error_1();
throw:Error2 ->
handle_error_2();
_:Error ->
internal_error()
end.
The problem with this solution is that you lose the stack trace with the try...catch block.
Instead of this, a better solution is:
insert() ->
case catch execute() of
ok -> all_ok;
{FuncName, Error} ->
handle_error(FuncName, Error);
{'EXIT', Error} ->
internal_error(Error)
end.
execute() ->
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert().
This way you have the full error stack on Error.
I have faced exactly the same question when writing my own REST services.
Let's start with the philosophy:
I like to think of my applications like a box. On the inside of the box are all of the parts I built and have direct control over. If something breaks here, it's my fault, it should crash, and I should read about it in an error log. On the edge of the box are all of the connection points to the outside world - these are not to be trusted. I avoid exception handling in the inside parts and use it as needed for the outer edge.
On similar projects I have worked on:
I usually have about a dozen checks on the user input. If something looks bad, I log it and return an error to the user. Having a stack trace isn't particularly meaningful to me - if the user forgot a parameter there is nothing in my code to hunt down and fix. I'd rather see a text log that says something like: “at 17:35, user X accessed path Y but was missing parameter Z”.
I organize my checks into functions that return ok or {error, string()}. The main function just iterates over the checks and returns ok if they all pass, otherwise it returns the first error, which is then logged. Inside of my check functions I use exception handling as needed because I can't possibly consider all of the ways users can screw up.
As suggested by my colleagues, you can alternatively have each check throw an exception instead of using a tuple.
As for your implementation, I think your idea of using a single exception handler is a good one if you only have the single check. If you end up needing more checks you may want to implement something like I described so that you can have more specific logging.

How to catch Exception Message in Erlang?

This is the Exception message thrown by Gen_server when its not started.
(ankit#127.0.0.1)32> R11 = system_warning:self_test("SysWarn").
** exception exit: {noproc,
{gen_server,call,
[system_warning_sup,
{start_child,
{system_warning_SysWarn,
{system_warning,start_link,[{system_warning_SysWarn}]},
permanent,10,worker,
[system_warning]}},
infinity]}}
in function gen_server:call/3
in call from system_warning_sup:'-start_child/1-lc$^0/1-0-'/1
in call from system_warning:self_test/1
(ankit#127.0.0.1)33> R11.
* 1: variable 'R11' is unbound
Now, What I want to do is to catch this exception message & put into variable R11 (showed above as unbound). I want to do so because if gen_sever is not started then I want to start after getting this message. I also tried using handle_info but not able to trap the exception or may be not able to implement it correctly. Can any body please help me with this problem providing some code for example.
Both the answers from #W55tKQbuRu28Q4xv and #Zed are correct but a little terse. :-)
There are two ways to locally catch an error: catchand try. Both will also catch non-local returns generated by throw.
catch is the older and simpler of the two and has the syntax catch Expr. If an error occurs in the expression being evaluated then catch returns {'EXIT',ErrorValue}, otherwise it just returns the value of the expression. One problem with it is that there is no way to see how the error return value has been generated so it can easily be faked in the expression. In the same way you can't see if the return value comes from a throw. N.B. this is not a bug but a feature. Also it is a prefix operator with a low priority so you would normally use it like:
R11 = (catch system_warning:self_test (....))
to avoid confusion. This was a mistake, it should have been catch ... end.
throw is more complex and allows you much greater control over over what to catch and how to handle both the normal returns and error/non-local returns. See the manual for a full description. #Zed's example shows the simplest case which catches everything.
> try
> R11 = system_warning:self_test("SysWarn")
> catch
> Ex:Type -> {Ex,Type,erlang:get_stacktrace()}
> end.
Try to use 'catch':
R11 = catch system_warning:self_test (....)