http://okmij.org/ftp/Haskell/misc.html#catchMonadIO
The ability to use functions catch
, bracket
, catchDyn
, etc. in
MonadIO other than IO itself has been a fairly frequently requested
feature:
http://www.haskell.org/pipermail/glasgowhaskellusers/2003September/005660.html
http://haskell.org/pipermail/libraries/2003February/000774.html
The reason it is not implemented is because these functions cannot be defined for a general MonadIO. However, these functions can be easily defined for a large and interesting subset of MonadIO. The following code demonstrates that. It uses no extensions (other than those needed for the Monad Transformer Library itself), patches no compilers, and proposes no extensions. The generic catch has been useful in a database library (Takusen), where many operations work in a monad (ReaderT Session IO): IO with the environment containing the database session data. Many other foreign libraries have a pattern of passing around various handles, which are better hidden in a monad. Still, we should be able to handle IO errors and user exceptions that arise in these computations.
 data MyException = MyException String
 class MonadIO m => CaughtMonadIO m where
 catchDyn :: (Typeable e, CaughtMonadIO m) => m a > (e > m a) > m a
Documentation
class MonadIO m => CaughtMonadIO m whereSource
The implementation is quite trivial.
CaughtMonadIO IO  
(Monoid w, CaughtMonadIO m) => CaughtMonadIO (WriterT w m)  The following instances presume that an exception that occurs in

CaughtMonadIO m => CaughtMonadIO (StateT s m)  
(CaughtMonadIO m, Error e) => CaughtMonadIO (ErrorT e m)  
CaughtMonadIO m => CaughtMonadIO (ReaderT r m)  The following is almost verbatim from 
(Monoid w, CaughtMonadIO m) => CaughtMonadIO (RWST r w s m) 
catchDyn :: (Typeable e, CaughtMonadIO m) => m a > (e > m a) > m aSource