How to catch all exceptions that could be caught?

Hi, With Prelude.catch, I could write "catch () $ \_ -> return Nothing". But with Control.Exception.catch, I must specify a type for the "_". What should I do? PS: In Java document, a function declaration would tell us both the incoming args and outgoing, AND what exceptions would it throw. But it does not seem to exist in Haskell document? And the most awful part is that even when the program failed with error message, I still did not know what exception was this. Take "recv: does not exist (Connection refused)" for example. -- 竹密岂妨流水过 山高哪阻野云飞

On 01/12/12 13:03, Magicloud Magiclouds wrote:
Hi, With Prelude.catch, I could write "catch () $ \_ -> return Nothing". But with Control.Exception.catch, I must specify a type for the "_". What should I do?
Use SomeException for the type, as it is the base of the exception hierarchy. (Although Haskell does not have classes in the OOP sense and therefore does not have a built-in means of expressing subtype relations, it emulates this in a somewhat awkward manner for exceptions.) Cheers, Greg

On 12 January 2012 17:34, Gregory Crosswhite
On 01/12/12 13:03, Magicloud Magiclouds wrote:
Hi, With Prelude.catch, I could write "catch () $ \_ -> return Nothing". But with Control.Exception.catch, I must specify a type for the "_". What should I do?
Use SomeException for the type, as it is the base of the exception hierarchy.
But it is usually recommended that you *don't* do this, as it even captures Ctrl-c invocations: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Yes, that is a problem. But consider my PS in original mail, I have no
idea what exception should I catch. Where could I get that
information?
On Thu, Jan 12, 2012 at 2:49 PM, Ivan Lazar Miljenovic
On 12 January 2012 17:34, Gregory Crosswhite
wrote: On 01/12/12 13:03, Magicloud Magiclouds wrote:
Hi, With Prelude.catch, I could write "catch () $ \_ -> return Nothing". But with Control.Exception.catch, I must specify a type for the "_". What should I do?
Use SomeException for the type, as it is the base of the exception hierarchy.
But it is usually recommended that you *don't* do this, as it even captures Ctrl-c invocations: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception...
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- 竹密岂妨流水过 山高哪阻野云飞

On 01/12/12 16:58, Magicloud Magiclouds wrote:
Yes, that is a problem. But consider my PS in original mail, I have no idea what exception should I catch. Where could I get that information?
In my experience, exceptions fall into three categories. First, when performing IO, some functions throw an exception instead of returning an error code, as is the case for many of the functions in System.IO; however, in these cases the exceptions that can be thrown are clearly documented. Second, when a bug in your code has caused it to reach a point where it can no longer proceed, such as when there is a deadlock, when there is an infinite loop, when you violated a precondition of a pure function by for example calling "head" on an empty list, etc.; in such cases it is very unlikely that you would even want to catch and gracefully recover from them, so an exception specification would not help you very much anyway. Third, when you are running someone else's code and you want to be able to catch any exceptions it throws so that you can handle the error reporting yourself; in this case the only thing that you care about is whether the exception is an AsyncException or not, since if it is an AsyncException then you should almost certainly should just let it propagate up the call stack rather than dealing with it yourself. Incidentally, in all of these cases catching *all* exceptions is a bad idea unless you really know what you are doing for the reasons that others here have pointed out, so I apologize for misleading you with that suggestion. Cheers, Greg

Thank you so much. I was always confused by what exception should I catch.
On Thu, Jan 12, 2012 at 3:49 PM, Gregory Crosswhite
On 01/12/12 16:58, Magicloud Magiclouds wrote:
Yes, that is a problem. But consider my PS in original mail, I have no idea what exception should I catch. Where could I get that information?
In my experience, exceptions fall into three categories.
First, when performing IO, some functions throw an exception instead of returning an error code, as is the case for many of the functions in System.IO; however, in these cases the exceptions that can be thrown are clearly documented.
Second, when a bug in your code has caused it to reach a point where it can no longer proceed, such as when there is a deadlock, when there is an infinite loop, when you violated a precondition of a pure function by for example calling "head" on an empty list, etc.; in such cases it is very unlikely that you would even want to catch and gracefully recover from them, so an exception specification would not help you very much anyway.
Third, when you are running someone else's code and you want to be able to catch any exceptions it throws so that you can handle the error reporting yourself; in this case the only thing that you care about is whether the exception is an AsyncException or not, since if it is an AsyncException then you should almost certainly should just let it propagate up the call stack rather than dealing with it yourself.
Incidentally, in all of these cases catching *all* exceptions is a bad idea unless you really know what you are doing for the reasons that others here have pointed out, so I apologize for misleading you with that suggestion.
Cheers, Greg
-- 竹密岂妨流水过 山高哪阻野云飞

Use SomeException for the type, as it is the base of the exception hierarchy.
But it is usually recommended that you *don't* do this, as it even captures Ctrl-c invocations:
I think there are situation when it is justified to catch almost all exceptions. And people do that a lot, which often leads to ctrl-c not properly working (e.g. we had this in HUnit before 1.2.4.2). The way I deal with this is: someAction `catches` [ -- Re-throw AsyncException, otherwise execution will not terminate -- on SIGINT (ctrl-c). All AsyncExceptions are re-thrown (not -- just UserInterrupt) because all of them indicate severe -- conditions and should not occur during normal operation. Handler (\e -> throw (e :: AsyncException)), Handler (\e -> yourHandler $ e :: SomeException) ] Cheers, Simon

On 01/12/12 17:07, Simon Hengel wrote:
I think there are situation when it is justified to catch almost all exceptions. And people do that a lot, which often leads to ctrl-c not properly working (e.g. we had this in HUnit before 1.2.4.2).
Indeed, and in fact this situation is a very natural occurrence whenever you are writing code that takes an arbitrary IO action, executes it, and then returns either the result or the exception that it threw. The code that I last used for this took advantage of catchJust and looked roughly like the following: execute :: IO a → IO (Either SomeException a) execute action = catchJust (\e → case fromException e of {Just (_ :: AsyncException) → Nothing; _ → Just e}) (Right <$> action) (return . Left) Cheers, Greg

On 01/12/12 17:23, Gregory Crosswhite wrote:
Indeed, and in fact this situation is a very natural occurrence whenever you are writing code that takes an arbitrary IO action, executes it, and then returns either the result or the exception that it threw. The code that I last used for this took advantage of catchJust and looked roughly like the following:
execute :: IO a → IO (Either SomeException a) execute action = catchJust (\e → case fromException e of {Just (_ :: AsyncException) → Nothing; _ → Just e}) (Right <$> action) (return . Left)
Cheers, Greg
Ugh, I have no idea why the spacing got eaten; it was meant to look like: execute :: IO a -> IO (Either SomeException a) execute action = catchJust (\e -> case fromException e of Just (_ :: AsyncException) -> Nothing; _ -> Just e ) (Right <$> action) (return . Left) Cheers, Greg
participants (4)
-
Gregory Crosswhite
-
Ivan Lazar Miljenovic
-
Magicloud Magiclouds
-
Simon Hengel