diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@
   * e.g. "can raise X, Y, and Z", or "raises exactly X and Y but none others"
 * Extensible
 * Ability to call code that raises some subset of errors
+* Handle (and eliminate) exceptions from the context
 
 # Approach
 
diff --git a/library/Control/Monad/Cleanup/Class.hs b/library/Control/Monad/Cleanup/Class.hs
--- a/library/Control/Monad/Cleanup/Class.hs
+++ b/library/Control/Monad/Cleanup/Class.hs
@@ -1,18 +1,17 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TypeFamilies     #-}
+{-# LANGUAGE TypeOperators    #-}
 
 module Control.Monad.Cleanup.Class (MonadCleanup (..)) where
 
 import           Control.Exception
 import           Control.Monad.Rescue
 
-import           Data.WorldPeace
-
 -- | Safely work with resources when an asynchronous exception may be thrown
-class (Raises m SomeException, MonadRescue m) => MonadCleanup m where
+class (m `Raises` SomeException, MonadRescueFrom m m) => MonadCleanup m where
   cleanup
-    :: m resource                                   -- ^ Acquire some resource
-    -> (resource -> OpenUnion (Errors m) -> m _ig1) -- ^ Cleanup and re-raise
-    -> (resource ->                         m _ig2) -- ^ Cleanup normally
-    -> (resource ->                         m a)    -- ^ Inner action to perform with the resource
+    :: m resource                          -- ^ Acquire some resource
+    -> (resource -> ErrorCase m -> m _ig1) -- ^ Cleanup and re-raise
+    -> (resource ->                m _ig2) -- ^ Cleanup normally
+    -> (resource ->                m a)    -- ^ Inner action to perform with the resource
     -> m a
diff --git a/library/Control/Monad/Raise/Class.hs b/library/Control/Monad/Raise/Class.hs
--- a/library/Control/Monad/Raise/Class.hs
+++ b/library/Control/Monad/Raise/Class.hs
@@ -3,12 +3,16 @@
 {-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE MagicHash            #-}
 {-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE TypeOperators        #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 -- | The 'MonadRaise' class, which is an effect for
 --   early escape / happy path programming with an exception side channel
 
-module Control.Monad.Raise.Class (MonadRaise (..)) where
+module Control.Monad.Raise.Class
+  ( MonadRaise (..)
+  , ErrorCase
+  ) where
 
 import           Control.Exception
 
@@ -86,8 +90,11 @@
   --
   -- >>> maybeBoom 42
   -- Nothing
-  raise :: Subset err (OpenUnion (Errors m)) => err -> m a
+  raise :: Subset err (ErrorCase m) => err -> m a
 
+-- | Type alias representing the concrete union of the monad's errors
+type ErrorCase m = OpenUnion (Errors m)
+
 instance MonadRaise [] where
   type Errors [] = '[()]
   raise _ = []
@@ -121,9 +128,13 @@
   type Errors (IdentityT m) = Errors m
   raise = lift . raise
 
-instance MonadRaise m => MonadRaise (MaybeT m) where
-  type Errors (MaybeT m) = Errors m
-  raise = lift . raise
+instance
+  ( () `IsMember` Errors m
+  , MonadRaise m
+  )
+  => MonadRaise (MaybeT m) where
+    type Errors (MaybeT m) = Errors m
+    raise err = MaybeT $ raise err
 
 instance MonadRaise m => MonadRaise (ReaderT cfg m) where
   type Errors (ReaderT cfg m) = Errors m
diff --git a/library/Control/Monad/Raise/Constraint.hs b/library/Control/Monad/Raise/Constraint.hs
--- a/library/Control/Monad/Raise/Constraint.hs
+++ b/library/Control/Monad/Raise/Constraint.hs
@@ -4,9 +4,15 @@
 
 -- | Declare which exceptions may be raised/rescued in a given context
 module Control.Monad.Raise.Constraint
-  ( Raises
+  ( -- * Permissive
+
+    Raises
   , RaisesAtLeast
+
+    -- * Precise
+
   , RaisesOnly
+  , RaisesOne
   ) where
 
 import           Control.Monad.Raise.Class
@@ -15,10 +21,14 @@
 import           Data.WorldPeace.Subset.Class
 
 -- | Raises this exception, but potentially others
-type Raises m err = Subset err (OpenUnion (Errors m))
+type Raises m err = Subset err (ErrorCase m)
 
 -- | May raise errors, including the provided list
-type RaisesAtLeast m errs = Subset (OpenUnion errs) (OpenUnion (Errors m))
+type RaisesAtLeast m errs = Subset (OpenUnion errs) (ErrorCase m)
 
 -- | Restrict exceptions to exactly this list
 type RaisesOnly m errs = errs ~ Errors m
+
+-- | Raises an exception, guaranteed to NOT be the outer union
+type RaisesOne m err = IsMember err (Errors m)
+
diff --git a/library/Control/Monad/Rescue.hs b/library/Control/Monad/Rescue.hs
--- a/library/Control/Monad/Rescue.hs
+++ b/library/Control/Monad/Rescue.hs
@@ -1,5 +1,7 @@
-{-# LANGUAGE LambdaCase   #-}
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE LambdaCase       #-}
+{-# LANGUAGE TypeFamilies     #-}
+{-# LANGUAGE TypeOperators    #-}
 
 -- | Rescue semantics & helpers
 --
@@ -11,6 +13,10 @@
 
 module Control.Monad.Rescue
   ( rescue
+  , handle
+
+  -- * Guaranteed runs
+
   , reattempt
   , onRaise
   , lastly
@@ -18,14 +24,18 @@
   -- * Reexports
 
   , module Control.Monad.Raise
+
   , module Control.Monad.Rescue.Class
+  , module Control.Monad.Rescue.Constraint
   ) where
 
 import           Data.Result.Types
 import           Data.WorldPeace
 
 import           Control.Monad.Raise
+
 import           Control.Monad.Rescue.Class
+import           Control.Monad.Rescue.Constraint
 
 import           Numeric.Natural
 
@@ -57,17 +67,28 @@
 -- :}
 --
 -- >>> handler = catchesOpenUnion (\foo -> "Foo: " <> show foo, \bar -> "Bar:" <> show bar)
--- >>> rescue (goesBoom 42) (pure . handler)
+-- >>> rescue (goesBoom 42) (pure . handler) :: Rescue MyErrs String
 -- RescueT (Identity (Right "Foo: FooErr"))
 rescue
-  :: ( MonadRescue m
-     , RaisesOnly  m errs
-     )
-  => m a
-  -> (OpenUnion errs -> m a)
+  :: MonadRescueFrom n m
+  => n a
+  -> (ErrorCase n -> m a)
   -> m a
 rescue action handler = either handler pure =<< attempt action
 
+handle
+  :: ( MonadRaise        m
+     , MonadRescueFrom n m
+     , Handles     err n m
+     )
+  => n a
+  -> (err -> m a)
+  -> m a
+handle action handler =
+  either runHandler pure =<< attempt action
+  where
+    runHandler = openUnionHandle raise handler
+
 onRaise
   :: ( MonadRescue m
      , RaisesOnly  m errs
@@ -96,7 +117,14 @@
 
 -- | Run an additional step, and throw away the result.
 --   Return the result of the action passed.
-lastly :: (Contains (Errors m) (Errors m), MonadRescue m) => m a -> m b -> m a
+lastly
+  :: ( Errors m `Contains` Errors m
+     , MonadRaise m
+     , MonadRescueFrom m m
+     )
+  => m a
+  -> m b
+  -> m a
 lastly action finalizer = do
   errOrOk <- attempt action
   _       <- finalizer
diff --git a/library/Control/Monad/Rescue/Class.hs b/library/Control/Monad/Rescue/Class.hs
--- a/library/Control/Monad/Rescue/Class.hs
+++ b/library/Control/Monad/Rescue/Class.hs
@@ -1,39 +1,39 @@
-{-# LANGUAGE FlexibleContexts     #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE LambdaCase           #-}
-{-# LANGUAGE TypeFamilies         #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE LambdaCase            #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
 
 -- | The 'MonadRescue' class, meant for retrieving the success/failure branches
 
-module Control.Monad.Rescue.Class (MonadRescue (..)) where
+module Control.Monad.Rescue.Class (MonadRescueFrom (..)) where
 
 import           Data.Functor
-
 import           Data.WorldPeace
 
 import           Exception
 
-import           Control.Monad.Raise.Class
-import           Control.Monad.Raise.Constraint
-
+import           Control.Monad.Base
 import           Control.Monad.Cont
 
+import           Control.Monad.Raise
+
 import           Control.Monad.Trans.Except
 import           Control.Monad.Trans.Identity
 import           Control.Monad.Trans.Maybe
 import           Control.Monad.Trans.Reader
 
-import qualified Control.Monad.RWS.Lazy         as Lazy
-import qualified Control.Monad.RWS.Strict       as Strict
-
-import qualified Control.Monad.State.Lazy       as Lazy
-import qualified Control.Monad.State.Strict     as Strict
+import qualified Control.Monad.RWS.Lazy       as Lazy
+import qualified Control.Monad.RWS.Strict     as Strict
 
-import qualified Control.Monad.Writer.Lazy      as Lazy
-import qualified Control.Monad.Writer.Strict    as Strict
+import qualified Control.Monad.State.Lazy     as Lazy
+import qualified Control.Monad.State.Strict   as Strict
 
-import           Data.WorldPeace.Subset.Class
+import qualified Control.Monad.Writer.Lazy    as Lazy
+import qualified Control.Monad.Writer.Strict  as Strict
 
 -- $setup
 --
@@ -42,6 +42,7 @@
 -- >>> :set -XTypeApplications
 --
 -- >>> import Control.Monad.Trans.Rescue
+-- >>> import Data.Functor.Identity
 -- >>> import Data.Proxy
 -- >>> import Data.WorldPeace as OpenUnion
 --
@@ -50,7 +51,8 @@
 -- >>> data QuuxErr = QuuxErr deriving Show
 
 -- | Pull a potential error out of the surrounding context
-class MonadRaise m => MonadRescue m where
+-- NOTE that the target `m` may not even be aware of Raise/Rescue. It's an escape to the "normal" world
+class (Monad m, MonadRaise n) => MonadRescueFrom n m where
   -- | Attempt some action, exposing the success and error branches
   --
   --  ==== __Examples__
@@ -63,96 +65,187 @@
   --        else raise FooErr
   -- :}
   --
-  -- >>> runRescue . attempt $ goesBoom 42
-  -- Right (Left (Identity FooErr))
+  -- >>> :{
+  --   result :: Identity (Either (OpenUnion '[FooErr, BarErr]) Int)
+  --   result = attempt $ goesBoom 42
+  -- :}
   --
-  -- Where @Identity fooErr@ is the selection of the 'OpenUnion'.
-  -- In practice you would handle the 'OpenUnion' like so:
+  -- >>> result
+  -- Identity (Left (Identity FooErr))
   --
-  -- >>> let handleErr = catchesOpenUnion (show, show)
-  -- >>> let x = attempt (goesBoom 42) >>= pure . either handleErr show
-  -- >>> runRescue x
-  -- Right "FooErr"
-  attempt :: m a -> m (Either (OpenUnion (Errors m)) a)
+  -- Where @Identity FooErr@ is the selection of the 'OpenUnion'.
+  attempt :: n a -> m (Either (ErrorCase n) a)
 
-instance MonadRescue Maybe where
-  attempt = return . \case
+instance Monad n => MonadRescueFrom Maybe n where
+  attempt = pure . \case
     Nothing -> Left $ openUnionLift ()
     Just x  -> Right x
 
-instance MonadRescue [] where
+instance Monad m => MonadRescueFrom [] m where
   attempt = return . \case
     []      -> Left $ include ()
     (a : _) -> Right a
 
-instance MonadRescue (Either (OpenUnion errs)) where
-  attempt action = Right action
+instance Monad m => MonadRescueFrom (Either (OpenUnion errs)) m where
+  attempt action = pure action
 
-instance MonadRescue IO where
+instance MonadIO m => MonadRescueFrom IO m where
   attempt action =
-    tryIO action <&> \case
+    liftIO (tryIO action) <&> \case
       Right val  -> Right val
       Left ioExc -> Left $ include ioExc
 
-instance MonadRescue m => MonadRescue (MaybeT m) where
-  attempt (MaybeT action) = MaybeT . fmap sequence $ attempt action
+instance
+  ( Monad m
+  , MonadRescueFrom n m
+  , n `RaisesOne` ()
+  )
+  => MonadRescueFrom (MaybeT n) m where
+    attempt (MaybeT action) =
+      attempt action <&> \case
+        Right (Just val) -> Right val
+        Right Nothing    -> Left $ include ()
+        Left errs        -> Left errs
 
-instance MonadRescue m => MonadRescue (IdentityT m) where
-  attempt (IdentityT action) = lift (attempt action)
+instance MonadRescueFrom n m => MonadRescueFrom (IdentityT n) m where
+  attempt (IdentityT action) = attempt action
 
 instance
-  ( MonadRescue m
-  , Contains (Errors m) errs
+  ( MonadBase       n m
+  , MonadRescueFrom n n
+  , Contains (Errors n) errs
   )
-  => MonadRescue (ExceptT (OpenUnion errs) m) where
-  attempt (ExceptT action) =
-    lift $
-      attempt action <&> \case
-        Left err       -> Left $ include err
-        Right errOrVal -> errOrVal
+  => MonadRescueFrom n (ExceptT (OpenUnion errs) m) where
+    attempt = liftBase . attempt
 
-instance MonadRescue m => MonadRescue (ReaderT cfg m) where
-  attempt = mapReaderT attempt
+instance
+  ( Monad             m
+  , MonadBase       n m
+  , MonadRaise      n
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (ReaderT cfg n) (ReaderT cfg m) where
+    attempt = mapReaderT attempt
 
-instance (Monoid w, MonadRescue m) => MonadRescue (Lazy.WriterT w m) where
-  attempt = Lazy.mapWriterT runner2
+instance
+  ( Monad               m
+  , MonadBase       n   m
+  , MonadRaise      n
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (ReaderT cfg m) where
+    attempt = liftBase . attempt
 
-instance (Monoid w, MonadRescue m) => MonadRescue (Strict.WriterT w m) where
-  attempt = Strict.mapWriterT runner2
+instance
+  ( Monoid w
+  , MonadBase       n m
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (Lazy.WriterT w n) (Lazy.WriterT w m) where
+    attempt = Lazy.mapWriterT runner2
 
-instance MonadRescue m => MonadRescue (Lazy.StateT s m) where
-  attempt = Lazy.mapStateT runner2
+instance
+  ( Monoid w
+  , MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (Lazy.WriterT w m) where
+    attempt = liftBase . attempt
 
-instance MonadRescue m => MonadRescue (Strict.StateT s m) where
-  attempt = Strict.mapStateT runner2
+instance
+  ( Monoid w
+  , MonadBase       n m
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (Strict.WriterT w n) (Strict.WriterT w m) where
+    attempt = Strict.mapWriterT runner2
 
-instance (Monoid w, MonadRescue m) => MonadRescue (Lazy.RWST r w s m) where
-  attempt = Lazy.mapRWST runner3
+instance
+  ( Monoid w
+  , MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (Strict.WriterT w m) where
+    attempt = liftBase . attempt
 
-instance (Monoid w, MonadRescue m) => MonadRescue (Strict.RWST r w s m) where
-  attempt = Strict.mapRWST runner3
+instance
+  ( MonadBase       n m
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (Lazy.StateT s n) (Lazy.StateT s m) where
+    attempt = Lazy.mapStateT runner2
 
-instance MonadRescue m => MonadRescue (ContT r m) where
-  attempt = withContT $ \b_mr current -> b_mr =<< attempt (pure current)
+instance
+  ( MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (Lazy.StateT s m) where
+    attempt = liftBase . attempt
 
+instance
+  ( MonadBase       n m
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (Strict.StateT s n) (Strict.StateT s m) where
+    attempt = Strict.mapStateT runner2
+
+instance
+  ( Monoid w
+  , MonadBase n m
+  , MonadRescueFrom n m
+  )
+  => MonadRescueFrom (Lazy.RWST r w s n) (Lazy.RWST r w s m) where
+    attempt = Lazy.mapRWST runner3
+
+instance
+  ( MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (Strict.StateT s m) where
+    attempt = liftBase . attempt
+
+instance
+  ( Monoid w
+  , MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (Strict.RWST r w s m) where
+    attempt = liftBase . attempt
+
+instance
+  ( MonadBase       n m
+  , MonadRescueFrom n n
+  )
+  => MonadRescueFrom n (ContT r m) where
+    attempt = liftBase . attempt
+
+instance forall m r . (MonadRescueFrom (ContT r m) m) => MonadRescueFrom (ContT r m) (ContT r m) where
+  attempt =
+    withContT $ \b_mr (current :: a) ->
+      b_mr =<< attempt (pure current :: ContT r m a)
+
 runner2
-  :: ( MonadRescue m
-     , RaisesOnly  m errs
+  :: forall m n errs a w .
+     ( MonadBase n m
+     , MonadRescueFrom n m
+     , n `RaisesOnly` errs
      )
-  => m (a, w)
-  -> m (Either (OpenUnion errs) a, w)
+  => n (a, w)
+  -> m (Either (ErrorCase n) a, w)
 runner2 inner = do
-  (a, w)   <- inner
-  errOrVal <- attempt (pure a)
-  return (errOrVal, w)
+  (val, log')  <- liftBase inner
+  result <- attempt (pure val :: n a)
+  return (result, log')
 
 runner3
-  :: ( MonadRescue m
-     , RaisesOnly  m errs
+  :: forall m n errs a s w .
+     ( MonadBase       n m
+     , MonadRescueFrom n m
+     , n `RaisesOnly` errs
      )
-  => m (a, b, c)
-  -> m (Either (OpenUnion errs) a, b, c)
+  => n (a, s, w)
+  -> m (Either (OpenUnion errs) a, s, w)
 runner3 inner = do
-  (a, s, w) <- inner
-  errOrVal  <- attempt (pure a)
-  return (errOrVal, s, w)
+  (val, state, log') <- liftBase inner
+  result             <- attempt (pure val :: n a)
+  return (result, state, log')
diff --git a/library/Control/Monad/Rescue/Constraint.hs b/library/Control/Monad/Rescue/Constraint.hs
new file mode 100644
--- /dev/null
+++ b/library/Control/Monad/Rescue/Constraint.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE ConstraintKinds  #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+module Control.Monad.Rescue.Constraint
+  ( Handles
+  , MonadRescue
+  ) where
+
+import           Control.Monad.Raise.Class
+import           Control.Monad.Rescue.Class
+
+import           Data.WorldPeace
+
+-- | Express the ability to 'handle' / eliminate an exception case
+type Handles err n m
+  =  ( ElemRemove       err (Errors n)
+     , Contains (Remove err (Errors n)) (Errors m)
+     )
+
+-- | Rescue from the existing context only
+--
+-- Note: cannot 'handle' (elimininate) exceptions
+type MonadRescue m = MonadRescueFrom m m
diff --git a/library/Control/Monad/Trans/Cleanup/Types.hs b/library/Control/Monad/Trans/Cleanup/Types.hs
--- a/library/Control/Monad/Trans/Cleanup/Types.hs
+++ b/library/Control/Monad/Trans/Cleanup/Types.hs
@@ -1,9 +1,11 @@
-{-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE LambdaCase           #-}
-{-# LANGUAGE ScopedTypeVariables  #-}
-{-# LANGUAGE TypeFamilies         #-}
-{-# LANGUAGE TypeOperators        #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE LambdaCase            #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
 
 -- | The 'CleanupT' transformer for adding async exceptions to a stack
 
@@ -15,13 +17,16 @@
 import           Control.Applicative
 import           Control.Monad
 
+import           Control.Monad.Base
 import           Control.Monad.Catch        as Catch
 import           Control.Monad.Cleanup
 import           Control.Monad.Fix
 import           Control.Monad.IO.Class
 import           Control.Monad.Trans.Class
 
+import           Data.Functor
 import           Data.Functor.Contravariant
+
 import           Data.WorldPeace
 
 -- | Adds 'SomeException' to an exception stack,
@@ -76,33 +81,6 @@
 instance MonadThrow m => MonadThrow (CleanupT m) where
   throwM = CleanupT . throwM
 
-instance
-  ( Contains (Errors m) (Errors m)
-  , MonadRaise m
-  , MonadThrow m
-  )
-  => MonadRaise (CleanupT m) where
-  type Errors (CleanupT m) = SomeException ': Errors m
-
-  raise err = openUnion raiser throwM errsUnion
-    where
-      errsUnion :: OpenUnion (SomeException ': Errors m)
-      errsUnion = include err
-
-      raiser :: Contains err (Errors m) => OpenUnion err -> CleanupT m a
-      raiser = CleanupT . raise
-
-instance
-  ( Contains (Errors m) (Errors m)
-  , MonadCatch  m
-  , MonadRescue m
-  )
-  => MonadRescue (CleanupT m) where
-  attempt action =
-    Catch.try action >>= \case
-      Left  e@(SomeException _) -> return . Left $ include e
-      Right result              -> attempt $ pure result
-
 instance MonadCatch m => MonadCatch (CleanupT m) where
   catch (CleanupT action) handler =
     CleanupT $ catch action (runCleanupT . handler)
@@ -127,7 +105,51 @@
 
 instance
   ( Contains (Errors m) (Errors m)
+  , MonadRaise m
+  , MonadThrow m
+  )
+  => MonadRaise (CleanupT m) where
+  type Errors (CleanupT m) = SomeException ': Errors m
+
+  raise err = openUnion raiser throwM errsUnion
+    where
+      errsUnion :: OpenUnion (SomeException ': Errors m)
+      errsUnion = include err
+
+      raiser :: Contains err (Errors m) => OpenUnion err -> CleanupT m a
+      raiser = CleanupT . raise
+
+instance MonadBase m m => MonadBase m (CleanupT m) where
+  liftBase = liftBaseDefault
+
+instance (Monad m, MonadRescue m) => MonadRescueFrom m (CleanupT m) where
+  attempt = CleanupT . attempt
+
+instance forall n m .
+  ( MonadRescueFrom n m
+  , MonadBase       n m
+  , MonadRescue     n
+  , MonadCatch      n
+  , Contains (Errors n) (Errors n)
+  , Contains (Errors n) (SomeException ': Errors n)
+  )
+  => MonadRescueFrom (CleanupT n) m where
+    attempt (CleanupT action) =
+      liftBase $
+        inner <&> \case
+          Left err          -> Left $ include err
+          Right (Left  err) -> Left $ include err
+          Right (Right val) -> Right val
+      where
+        inner =
+          Catch.try action >>= \case
+            Left  e@(SomeException _) -> return $ Left e
+            Right (val :: a)          -> Right <$> attempt (pure val :: n a)
+
+instance
+  ( Contains (Errors m) (Errors m)
   , Contains (Errors m) (SomeException ': Errors m)
+  , MonadBase m m
   , MonadRescue m
   , MonadMask   m
   )
diff --git a/library/Control/Monad/Trans/Rescue/Types.hs b/library/Control/Monad/Trans/Rescue/Types.hs
--- a/library/Control/Monad/Trans/Rescue/Types.hs
+++ b/library/Control/Monad/Trans/Rescue/Types.hs
@@ -12,11 +12,14 @@
   , runRescue
   ) where
 
+import Prelude
+
 import           Control.Monad.Catch
 import           Control.Monad.Cont
 import           Control.Monad.Fix
 import           Control.Monad.Reader
 import           Control.Monad.Rescue
+import           Control.Monad.Base
 
 import           Data.Functor.Identity
 import           Data.WorldPeace
@@ -32,9 +35,12 @@
 runRescue = runIdentity . runRescueT
 
 mapRescueT
-  :: (m (Either (OpenUnion errs)  a) -> n (Either (OpenUnion errs') b))
-  -> RescueT errs m a -> RescueT errs' n b
-mapRescueT f (RescueT m) = RescueT $ f m
+  :: (  n (Either (OpenUnion errs)  a)
+     -> m (Either (OpenUnion errs') b)
+     )
+  -> RescueT errs  n a
+  -> RescueT errs' m b
+mapRescueT f (RescueT n) = RescueT $ f n
 
 instance Eq (m (Either (OpenUnion errs) a)) => Eq (RescueT errs m a) where
   RescueT a == RescueT b = a == b
@@ -60,6 +66,9 @@
 instance MonadTrans (RescueT errs) where
   lift action = RescueT (Right <$> action)
 
+instance MonadBase b m => MonadBase b (RescueT errs m) where
+  liftBase = liftBaseDefault
+
 instance MonadIO m => MonadIO (RescueT errs m) where
   liftIO io = RescueT $ do
     action <- liftIO io
@@ -86,8 +95,12 @@
   type Errors (RescueT errs m) = errs
   raise err = RescueT . pure $ raise err
 
-instance Monad m => MonadRescue (RescueT errs m) where
-  attempt (RescueT action) = RescueT (Right <$> action)
+instance
+  ( Monad       m
+  , MonadBase n m
+  )
+  => MonadRescueFrom (RescueT errs n) m where
+    attempt (RescueT action) = liftBase action
 
 instance MonadThrow m => MonadThrow (RescueT errs m) where
   throwM = lift . throwM
diff --git a/rescue.cabal b/rescue.cabal
--- a/rescue.cabal
+++ b/rescue.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
+-- This file has been generated from package.yaml by hpack version 0.34.2.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 3e4995b89bcb6d9791c2c448d52d59c9ca79e160013ba0d3fbad54936b417fe3
+-- hash: 6fb768a7355701f4063e91ba078ad7698c52571f65d298ebcf667cacd6a8b1a8
 
 name:           rescue
-version:        0.2.1
+version:        0.3.0
 synopsis:       More understandable exceptions
 description:    An error handling library focused on clarity and control
 category:       Error Handling
@@ -36,6 +36,7 @@
       Control.Monad.Raise.Constraint
       Control.Monad.Rescue
       Control.Monad.Rescue.Class
+      Control.Monad.Rescue.Constraint
       Control.Monad.Trans.Cleanup
       Control.Monad.Trans.Cleanup.Types
       Control.Monad.Trans.Rescue
@@ -58,6 +59,7 @@
     , mtl
     , text
     , transformers
+    , transformers-base
     , world-peace
   default-language: Haskell2010
 
@@ -83,6 +85,7 @@
     , quickcheck-instances
     , text
     , transformers
+    , transformers-base
     , world-peace
     , yaml
   default-language: Haskell2010
@@ -104,6 +107,7 @@
     , rio
     , text
     , transformers
+    , transformers-base
     , world-peace
   default-language: Haskell2010
 
@@ -118,6 +122,7 @@
       Control.Monad.Raise.Constraint
       Control.Monad.Rescue
       Control.Monad.Rescue.Class
+      Control.Monad.Rescue.Constraint
       Control.Monad.Trans.Cleanup
       Control.Monad.Trans.Cleanup.Types
       Control.Monad.Trans.Rescue
@@ -151,6 +156,7 @@
     , tasty-smallcheck
     , text
     , transformers
+    , transformers-base
     , world-peace
   default-language: Haskell2010
 
@@ -171,5 +177,6 @@
     , rescue
     , text
     , transformers
+    , transformers-base
     , world-peace
   default-language: Haskell2010
