PosixLike had error handling based on the ErrorT transformer. This didn't allow for good discrimination of caught exceptions, nor support any of the shiny nice utilities in Control.Exception (like finally, which warren had reimplemented for us, and bracket).
This change creates an mtl/transformers style typeclass, MonadException, and monad transformer for exceptions, ExceptionT, based on the extensible exception system in Control.Exception. It provides many of the utilities from Control.Exception, but in terms of the new typeclass, and then provides instances for IO, a transformer ExceptionT, and the lazy StateT transformer (eventually should have other transformers, too, I suppose, but that is the only one we use for now.)
PosixLike is now in terms of MonadException, and both ShellExec (by virtue of being a StateT), and TestExec (by virtue of using ExceptionT), and IO (by virtue of being IO) are now all monads where one can use the new exception system with type-based catch, bracket, finally, etc. In addition, some new catch variants are added that we use often (notably catchIOError).
This change was a long time coming, and serves to bring our exception handling practices up to modern usage, making it consistent with the up-to-date changes Evan made to the non-PosixLike code (as the interface is the same as Control.Exception's). It is also a requirement for two upcoming major changes: 1) support for break, continue, return and exit, and b) handling shell errors correctly (what we currently use andThenM and untilFailureM for).
- Mark