diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # ChangeLog for time-manager
 
+## 0.3.2
+
+* Add `stopAfterWithResult`. [#1069](https://github.com/yesodweb/wai/pull/1069)
+
 ## 0.3.1.1
 
 * Added `README.md` file and improved documentation of modules and functions.
diff --git a/System/ThreadManager.hs b/System/ThreadManager.hs
--- a/System/ThreadManager.hs
+++ b/System/ThreadManager.hs
@@ -19,6 +19,7 @@
     ThreadManager,
     newThreadManager,
     stopAfter,
+    stopAfterWithResult,
     KilledByThreadManager (..),
 
     -- * Fork
@@ -106,7 +107,25 @@
 -- to cleanup in all circumstances. If an exception is caught, it is rethrown
 -- after the cleanup is complete.
 stopAfter :: ThreadManager -> IO a -> (Maybe SomeException -> IO ()) -> IO a
-stopAfter (ThreadManager _timmgr var) action cleanup = do
+stopAfter mgr action cleanup =
+    stopAfterWithResult mgr action $ \mResult ->
+        case mResult of
+            Left err -> do
+                cleanup (Just err)
+                E.throwIO err
+            Right result -> do
+                cleanup Nothing
+                return result
+
+-- | Generalization of 'stopAfter' where the cleanup handler is allowed to construct the final result
+--
+-- Unlike in 'stopAfter', if an exception is thrown, it is not re-thrown after the cleanup
+-- handler completes; the cleanup handler itself can decide to rethrow it or compute a result.
+--
+-- @since 0.3.2
+stopAfterWithResult
+    :: ThreadManager -> IO a -> (Either SomeException a -> IO b) -> IO b
+stopAfterWithResult (ThreadManager _timmgr var) action cleanup = do
     E.mask $ \unmask -> do
         ma <- E.try $ unmask action
         m <- atomically $ do
@@ -117,9 +136,7 @@
             er = either Just (const Nothing) ma
             ex = KilledByThreadManager er
         forM_ ths $ \(ManagedThread wtid ref) -> lockAndKill wtid ref ex
-        case ma of
-            Left err -> cleanup (Just err) >> E.throwIO err
-            Right a -> cleanup Nothing >> return a
+        cleanup ma
 
 ----------------------------------------------------------------
 
diff --git a/time-manager.cabal b/time-manager.cabal
--- a/time-manager.cabal
+++ b/time-manager.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               time-manager
-version:            0.3.1.1
+version:            0.3.2
 license:            MIT
 license-file:       LICENSE
 maintainer:         kazu@iij.ad.jp
