[Haskell-cafe] Exceptions during exception unwinding

Duncan Coutts duncan.coutts at googlemail.com
Thu Oct 1 05:26:41 EDT 2009


On Thu, 2009-10-01 at 03:29 +0000, Brian Bloniarz wrote: 
> I had a question about onException & friends: what's the rationale
> for having:
> (error "foo") `onException` (error "bar")
> 
> give bar and not foo?

> I.e. why does an exception raised during exception handling get
> propagated past the exception that triggered the handler?

Because it's the obvious and sensible thing to do and it what every
other mainstream language with exceptions does. The behaviour you want,
to automatically discard any exceptions raised in the handler and to
always re-raise the original exception can be implemented using the
current semantics, but the reverse is not true.

> Most examples I can think for exception unwinding code would prefer the
> original exception be propagated

Then do not rethrow a different exception.

> This same argument applies to bracket, bracket_, bracketOnError & finally;
> even the common:
> > bracket openSomeHandle closeSomeHandle doAction
> If some error arises during doAction, there's a chance closeSomeHandle might fail
> (even a good chance, given that exception unwinding paths are usually poorly
> tested), and probably doAction has more accurate information about what went
> wrong than closeSomeHandle.

Then catch and ignore the exception from closeSomeHandle (though not all
exceptions or you'd block ^C etc). That said, how will you know that
closeSomeHandle ever works if you always ignore any exceptions it
raises?

For example in the case of your database transaction, having the
transaction fail and roll back is something your application may be set
up to handle. But transation failing during the rollback may be much
more catastrophic and may want to be treated differently. If it fails in
the rollback it might be leaking resources and at the very least you may
want to log it differently from just a transaction that was successfully
rolled back.

> This is just a thought; I hadn't seen this discussed somewhere. I know for
> example that Java has the same approach as the current Control.Exception, so
> there must be good arguments for that too. One that I can think of: using
> onException to rethrow an exception as a different type, though that's what
> mapException is for, correct?

mapException is for the case of exceptions raised by pure code.

As you say, being able to rethrow a different kind of exception, or
simply handle the exception there and then are useful.

I think using onException is the best one for your use case. If you
really really want to ignore an exception raised by rollback then you
have the tools available to do so. As I mentioned earlier do not just
catch and discard all exceptions, see:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#4

Duncan



More information about the Haskell-Cafe mailing list