Jason Dagit wrote:
On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <[EMAIL PROTECTED]> wrote:
Johannes Waldmann wrote:
with 6.10, the following does not typecheck:

foo `Control.Exception.catch` \ _ -> return bar

Ambiguous type variable `e' in the constraint:
     `Control.Exception.Exception e'

It is probably bad programming style anyway but what is the workaround?
As long as you're aware that it is bad programming style.  We deliberately
didn't include an easy way to do this, because we want people to think about
why they need to catch *all* exceptions (most of the time it's a bug).

Since the above is bad form, what should I be doing?  Could someone
please provide some examples or point me at the list of exceptions
that I can catch?  What about catching multiple types of exceptions?

Let's distinguish two kinds of exception handling:

1. Cleaning up. If you want to catch errors in order to clean up - release resources, remove temporary files, that sort of thing - then use bracket or finally. Behind the scenes, these catch all exceptions, but crucially they re-throw the exception after cleaning up, and they do the right block/unblock stuff for asynchronous exceptions.

2. Recovery. You want to catch certain kinds of exception in order to recover and do something else, e.g. when calling getEnv. In that case, I recommend using try or tryJust.

   tryJust (guard . isDoesNotExistError) $ getEnv "HOME"

it's good practice to separate the filter (the kinds of exception you're catching) from the code to handle them, and that's what tryJust does. There's some subtelty here to do with whether you need to be in "blocked" mode to handle the exception or not: if you're handling an exception you expect to be thrown asynchronously, then you probably want to use catch instead of try, because then the handler will run in blocked mode. But be careful not to tail-call out of the handler, because then the thread will stay in blocked mode, which will lead to strange problems later. A bit more background is here:

http://hackage.haskell.org/trac/ghc/ticket/2558

(hmm, perhaps exception handlers should be STM transactions. Then you wouldn't be able to accidentally tail-call out of the exception handler back into IO code, but you would be able to re-throw exceptions. Just a thought.)

As for the kinds of exception you can catch, nowadays you can catch any type that is an instance of Exception. A good place to start is the list of instances of Exception in the docs:

http://www.haskell.org/ghc/dist/stable/docs/libraries/base/Control-Exception.html#t%3AException

although that only contains types defined by the base package.

Others have commented on the backwards-compat issues, I don't have anything to add there.

Cheers,
        Simon
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to