
I'm trying to use the new (for me at least) extensible exceptions and I am little amazed that I cannot get catch, try or mapException to work without telling them which exceptions I want to catch. What is the rationale behind this? How does bracket manage to catch all exceptions? What should onException do? Is there some example code that uses these exceptions, or better documentation? Thanks in advance, Immanuel

Excerpts from Immanuel Litzroth's message of Wed Jan 07 16:53:30 -0600 2009:
I'm trying to use the new (for me at least) extensible exceptions and I am little amazed that I cannot get catch, try or mapException to work without telling them which exceptions I want to catch. What is the rationale behind this?
The rational is that it's normally not a good idea to simply gobble all exceptions; although the library makes it possible to do this anyway. You can either use the ScopedTypeVariables extension and do: ... `catch` \(e::SomeException) -> ... Or without an extension you can do: ... `catch` handler where handler :: SomeException -> IO a handler e = ... (It's really a matter of taste if you want to use a non-haskell98 extension, although considering that the new extensible exceptions library uses deriving data/typeable and existentials anyway, I think ScopedTypeVariables are the way to go.)
How does bracket manage to catch all exceptions? What should onException do?
onException takes an IO action and what to do if it fails - if the IO action fails, it is caught and your 'failure action' is run, followed by onException re-throwing the error.
Is there some example code that uses these exceptions, or better documentation?
The GHC docs don't have source-code links (don't know why,) but luckily in order to aid in using the new extensions system with older GHCs there has been a hackage package uploaded that provides the identical functionality: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/extensible-except... The source is here: http://hackage.haskell.org/packages/archive/extensible-exceptions/0.1.1.0/do... As for documentation e.g. haddock stuff, this is currently a bug as there is none: http://hackage.haskell.org/trac/ghc/ticket/2655 I recommend this paper for info, it's very easy to follow: http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf Austin

On Thu, Jan 8, 2009 at 12:32 AM, Austin Seipp
Excerpts from Immanuel Litzroth's message of Wed Jan 07 16:53:30 -0600 2009: ...
I am little amazed that I cannot get catch, try or mapException to work without telling them which exceptions I want to catch. What is the rationale behind this?
The rational is that it's normally not a good idea to simply gobble all exceptions; although the library makes it possible to do this anyway.
I'd advice always putting an additional generic catch-all at the top level, at least to present the user a (possibly generic) error message, just to stay in control. This avoids the possibility of having an unwanted/unknown behavior from the run-time stack (for example, having the web server returning a generic 500 Internal Server error report, filled with every sort of goods a cracker would be happy for). Cristiano

On Thu, Jan 8, 2009 at 6:36 AM, Cristiano Paris
This avoids the possibility of having an unwanted/unknown behavior from the run-time stack (for example, having the web server returning a generic 500 Internal Server error report, filled with every sort of goods a cracker would be happy for).
So the information should be written to the log rather than the browser, at least in production, but there's no reason not to catch the exception.
Cristiano
--Max

I recommend this paper for info, it's very easy to follow:
http://www.haskell.org/~simonmar/papers/ext-exceptions.pdfhttp://www.haskell.org/%7Esimonmar/papers/ext-exceptions.pdf
Austin
That paper cleared up most of my issues and it is amazing that it is not amongst the papers that are referenced at the top of the the page describing Control.Exception. Anyway, there is one more problem I have related to exceptions that is about forcing strictness. It relates to option parsing. I have an option -t that says which track from a file of tracks to print. So I go data Flags = TrackNumber !Int deriving(Read, Show, Eq) makeTrackNumber :: String -> Flags makeTrackNumber str = TrackNumber $ read str options = [GetOpt.Option ['t'] ["tracknumber"] (GetOpt.ReqArg makeTrackNumber "tracknumber") "number of track to show"] Now my main goes main = do args <- getArgs opts <- evaluate $ GetOpt.getOpt GetOpt.RequireOrder options args print "done getting the opts" case opts of ... which of course first prints "done getting opts" and then throws an exception if I give it a flag -t abc. What would be the way to proceed here? Do I increase the strictness or do I write a handler around my complete main? Even if I map the exception in makeTrackNumber to my very own exception how do I find out which exact call gave a problem i.e. which is the call stack at the moment the exception was thrown -- I might use makeTrackNumber in other contexts too. Thanks in advance, Immanuel

Immanuel Litzroth schrieb:
Anyway, there is one more problem I have related to exceptions that is about forcing strictness. It relates to option parsing. I have an option -t that says which track from a file of tracks to print. So I go
data Flags = TrackNumber !Int deriving(Read, Show, Eq)
makeTrackNumber :: String -> Flags makeTrackNumber str = TrackNumber $ read str
options = [GetOpt.Option ['t'] ["tracknumber"] (GetOpt.ReqArg makeTrackNumber "tracknumber") "number of track to show"]
Now my main goes main = do args <- getArgs opts <- evaluate $ GetOpt.getOpt GetOpt.RequireOrder options args print "done getting the opts" case opts of ...
which of course first prints "done getting opts" and then throws an exception if I give it a flag -t abc.
'evaluate' is strange here. Is it ok to put the print after the case ? But I have probably still not understood the problem. Let me point to two other issues: An elegant way to use GetOpt is: http://www.haskell.org/haskellwiki/High-level_option_handling_with_GetOpt I find it bad style to hide the exceptions, that can be raised. The type of an action should reflect what exceptions are to be expected. You can achieve this with Control.Monad.Exception.Synchronous from http://hackage.haskell.org/cgi-bin/hackage-scripts/package/explicit-exceptio... or Control.Monad.Error from http://hackage.haskell.org/cgi-bin/hackage-scripts/package/transformers For an application, using these techniques, see: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/equal-files
participants (5)
-
Austin Seipp
-
Cristiano Paris
-
Henning Thielemann
-
Immanuel Litzroth
-
Max Rabkin