Notes on Haskell Exceptions

Control.Exception

Anything in the Exception class can be thrown, and can be wrapped with the SomeException constructor:

data SomeException = forall e . Exception e => SomeException e

The Exception class has methods toException and fromException to convert your exception type e to and from SomeException respectively.

class (Typeable e, Show e) => Exception e where
    toException   :: e -> SomeException
    fromException :: SomeException -> Maybe e

The fromException method is just cast by default, which returns Nothing when applied to the wrong type.

So there's no sure way of knowing at a particular point in the code whether some exception has been thrown inside that is now causing its execution to be abandoned, unless you have just tried to catch that exact exception type. This suggests that creating a lot of knew Exception instances with other Exception values wrapped inside is not a good strategy. Instead we catch the IOException, wrap it up in another type e, and then return it in a function with a MonadError e m constraint.

The Exception Functions

Asynchronous Exceptions

The Exception Modules

IO

So my challenge is that I have an IO operation I want to run from some code in another monad, and I want to know that any IO exception it throws has been caught and wrapped up in an e.