diff --git a/Control/ContStuff.hs b/Control/ContStuff.hs
--- a/Control/ContStuff.hs
+++ b/Control/ContStuff.hs
@@ -14,33 +14,46 @@
   TypeFamilies #-}
 
 module Control.ContStuff
-  ( -- * The identity monad
-    Id(..),
-
-    -- * Monad transformers
+  ( -- * Monad transformers
     -- ** Identity transformer
     IdT(..),
-    -- ** Basic CPS monads
-    Cont, runCont, evalCont, modifyCont,
+    -- ** ContT
     ContT(..), runContT, evalContT, modifyContT,
-    -- ** Advanced CPS monads
-    -- *** Choice/nondeterminism
+    -- ** Choice/nondeterminism
     ChoiceT(..), runChoiceT, findFirst, findAll, listChoiceT, listA,
-    -- *** State
-    State, runState, evalState, execState,
+    -- ** Exceptions
+    EitherT(..), runEitherT, evalEitherT,
+    -- ** State
     StateT(..), runStateT, evalStateT, execStateT,
     -- ** Writer monads
-    OldWriter, runOldWriter, evalOldWriter, execOldWriter,
-    OldWriterT, runOldWriterT, evalOldWriterT, execOldWriterT,
     WriterT, runWriterT,
+    OldWriterT, runOldWriterT, evalOldWriterT, execOldWriterT,
 
+    -- * Monads
+    -- ** Identity monad
+    Id(..),
+    -- ** Cont
+    Cont, runCont, evalCont, modifyCont,
+    -- ** State
+    State, runState, evalState, execState,
+    -- ** Writer
+    OldWriter, runOldWriter, evalOldWriter, execOldWriter,
+
     -- * Effect classes
+    -- ** Abortion
     Abortable(..),
+    -- ** Call with current continuation
     CallCC(..), Label, labelCC, goto,
+    -- ** Exceptions
+    HasExceptions(..), catch, handle, finally, bracket, bracket_,
+    -- ** Lifting
+    Transformer(..),
     LiftBase(..), io,
+    -- ** Running
     Runnable(..),
+    -- ** State
     Stateful(..), getField, modify, modifyField, modifyFieldLazy, modifyLazy,
-    Transformer(..),
+    -- ** Logging support (writers)
     Writable(..),
 
     -- * Module reexports
@@ -49,12 +62,14 @@
   )
   where
 
+import qualified Control.Exception as E
 import Control.Applicative
 import Control.Arrow
 import Control.Monad
 import Control.Monad.Fix
 import Control.Monad.ST
 import Data.Monoid
+import Prelude hiding (catch)
 
 
 -- ================== --
@@ -255,6 +270,76 @@
 modifyCont = modifyContT
 
 
+-------------
+-- EitherT --
+-------------
+
+-- | Monad transformer for CPS computations with an additional exception
+-- continuation.
+
+newtype EitherT r e m a =
+  EitherT { getEitherT :: (a -> m r) -> (e -> m r) -> m r }
+
+instance Applicative m => Abortable (EitherT r e m) where
+  type Result (EitherT r e m) = r
+  abort x = EitherT $ \_ _ -> pure x
+
+instance Applicative (EitherT r e m) where
+  pure x = EitherT $ \k _ -> k x
+  EitherT cf <*> EitherT cx =
+    EitherT $ \k expk -> cf (\f -> cx (\x -> k (f x)) expk) expk
+
+instance Alternative m => Alternative (EitherT r e m) where
+  empty = EitherT $ \_ _ -> empty
+  EitherT c <|> EitherT d =
+    EitherT $ \k expk -> c k expk <|> d k expk
+
+instance CallCC (EitherT r e m) where
+  callCC f =
+    EitherT $ \k expk ->
+      getEitherT (f (\x -> EitherT $ \_ _ -> k x)) k expk
+
+instance HasExceptions (EitherT r e m) where
+  type Exception (EitherT r e m) = e
+  raise exp = EitherT $ \_ expk -> expk exp
+  try (EitherT c) = EitherT $ \k _ -> c (k . Right) (k . Left)
+
+instance Functor (EitherT r e m) where
+  fmap f (EitherT c) =
+    EitherT $ \k expk -> c (k . f) expk
+
+instance Monad (EitherT r e m) where
+  return x = EitherT $ \k _ -> k x
+  EitherT c >>= f =
+    EitherT $ \k expk ->
+      c (\x -> getEitherT (f x) k expk) expk
+
+instance Runnable (EitherT r e) r m a where
+  type Argument (EitherT r e) r m a = (a -> m r, e -> m r)
+  runT (k, expk) (EitherT c) = c k expk
+
+instance Transformer (EitherT r e) where
+  lift c = EitherT $ \k _ -> c >>= k
+
+instance Alternative m => Writable (EitherT r e m) r where
+  tell x = EitherT $ \k _ -> pure x <|> k ()
+
+instance (Functor m, Monoid w) => Writable (EitherT (r, w) e m) w where
+  tell x = EitherT $ \k _ -> fmap (second (`mappend` x)) (k ())
+
+
+-- | Run an 'EitherT' transformer.
+
+runEitherT :: (a -> m r) -> (e -> m r) -> EitherT r e m a -> m r
+runEitherT k expk (EitherT c) = c k expk
+
+
+-- | Run an 'EitherT' transformer returning an 'Either' result.
+
+evalEitherT :: Applicative m => EitherT (Either e a) e m a -> m (Either e a)
+evalEitherT (EitherT c) = c (pure . Right) (pure . Left)
+
+
 ---------
 -- IdT --
 ---------
@@ -346,6 +431,8 @@
 -- StateT --
 ------------
 
+-- | Monad transformer for stateful computations.
+
 newtype StateT r s m a =
   StateT { getStateT :: s -> (s -> a -> m r) -> m r }
 
@@ -364,7 +451,9 @@
     StateT $ \s0 k -> cf s0 (\s1 f -> cx s1 (\s2 x -> k s2 (f x)))
 
 instance CallCC (StateT r s m) where
-  callCC f = StateT $ \s0 k -> getStateT (f (\x -> StateT $ \s1 _ -> k s1 x)) s0 k
+  callCC f =
+    StateT $ \s0 k ->
+      getStateT (f (\x -> StateT $ \s1 _ -> k s1 x)) s0 k
 
 instance Functor (StateT r s m) where
   fmap f (StateT c) =
@@ -481,8 +570,89 @@
 
 -- | Jump to a label.
 
-goto :: Applicative m => Label m a -> a -> m b
-goto lk@(Label k) x = k x lk *> pure undefined
+goto :: Label m a -> a -> m ()
+goto lk@(Label k) x = k x lk
+
+
+-- | Monads with exception support.
+
+class HasExceptions m where
+  -- | The exception type.
+  type Exception m
+
+  -- | Raise an exception.
+  raise :: Exception m -> m a
+
+  -- | Run computation catching exceptions.
+  try :: m a -> m (Either (Exception m) a)
+
+instance HasExceptions (Either e) where
+  type Exception (Either e) = e
+  raise = Left
+  try = Right
+
+instance HasExceptions Maybe where
+  type Exception Maybe = ()
+  raise = const Nothing
+  try = Just . maybe (Left ()) Right
+
+instance HasExceptions IO where
+  type Exception IO = E.SomeException
+  raise = E.throwIO
+  try = E.try
+
+
+-- | Catch exceptions using an exception handler.
+
+catch :: (HasExceptions m, Monad m) => m a -> (Exception m -> m a) -> m a
+catch c h = try c >>= either h return
+
+
+-- | Catch exceptions using an exception handler (flip 'catch').
+
+handle :: (HasExceptions m, Monad m) => (Exception m -> m a) -> m a -> m a
+handle h c = try c >>= either h return
+
+
+-- | Run a final computation regardless of whether an exception was
+-- raised.
+
+finally :: (HasExceptions m, Monad m) => m a -> m b -> m a
+finally c d = try c >>= either (\exp -> d >> raise exp) (\x -> d >> return x)
+
+
+-- | Get a resource, run a computation, then release the resource, even
+-- if an exception is raised:
+--
+-- > bracket acquire release use
+--
+-- Please note that this function behaves slightly different from the
+-- usual 'E.bracket'.  If both the user and the releaser throw an
+-- exception, the user exception is significant.
+
+bracket :: (HasExceptions m, Monad m) => m res -> (res -> m b) -> (res -> m a) -> m a
+bracket acquire release use = do
+  resource <- acquire
+  result <- try (use resource)
+  try (release resource)
+  either raise return result
+
+
+-- | Initialize, then run, then clean up safely, even if an exception is
+-- raised:
+--
+-- > bracket_ init cleanup run
+--
+-- Please note that this function behaves slightly different from the
+-- usual 'E.bracket_'.  If both the user and the releaser throw an
+-- exception, the user exception is significant.
+
+bracket_ :: (HasExceptions m, Monad m) => m a -> m b -> m c -> m c
+bracket_ init cleanup run = do
+  init
+  result <- try run
+  try cleanup
+  either raise return result
 
 
 -- | Monads, which support lifting base monad computations.
diff --git a/contstuff.cabal b/contstuff.cabal
--- a/contstuff.cabal
+++ b/contstuff.cabal
@@ -1,5 +1,5 @@
 Name:          contstuff
-Version:       0.2.2
+Version:       0.3.0
 Category:      Control, Monads
 Synopsis:      Easy to use CPS-based monads
 Maintainer:    Ertugrul Söylemez <es@ertes.de>
