Edward Kmett\'s exceptions library does not provide a MonadMask instance for ExceptT.
Ben Gamari once asked about this and then concluded that it was explained
A class for monads which provide for the ability to account for all possible exit points from a computation, and to mask asynchronous exceptions. Continuation-based monads, and stacks such as
ErrorT e IOwhich provide for multiple failure modes, are invalid instances of this class.
When you use ErrorT/ExceptT with IO, having "multiple exit points" refers to the fact that you can have either a runtime exception or an exception thrown in the Monad. Either of which would end the computation.
runExceptT $ do
error "This is an exit point."
throwError "This is another exit point."
return 23
It would be possible to write a MonadMask for ExceptT that would be valid for all ExceptT e m a with the precondition that the underlying monad m is not IO. Hence the huge warning about using CatchT with IO (Doing so invalidates the MonadMask instance).