enclosed-exceptions 1.0.0.2 → 1.0.1
raw patch · 3 files changed
+51/−5 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Exception.Enclosed: catchDeep :: (Exception e, NFData a, MonadBaseControl IO m) => m a -> (e -> m a) -> m a
+ Control.Exception.Enclosed: tryDeep :: (Exception e, NFData a, MonadBaseControl IO m) => m a -> m (Either e a)
Files
- enclosed-exceptions.cabal +1/−1
- src/Control/Exception/Enclosed.hs +24/−3
- test/main.hs +26/−1
enclosed-exceptions.cabal view
@@ -1,5 +1,5 @@ name: enclosed-exceptions-version: 1.0.0.2+version: 1.0.1 synopsis: Catching all exceptions from within an enclosed computation description: Catching all exceptions raised within an enclosed computation, while remaining responsive to (external) asynchronous exceptions.
src/Control/Exception/Enclosed.hs view
@@ -35,8 +35,10 @@ catchAny , handleAny , tryAny+ , catchDeep , catchAnyDeep , handleAnyDeep+ , tryDeep , tryAnyDeep , catchIO , handleIO@@ -90,6 +92,13 @@ liftBaseWith (\runInIO -> withAsync (runInIO m) waitCatch) >>= either (return . Left) (liftM Right . restoreM) +-- | An extension to @catch@ which ensures that the return value is fully+-- evaluated. See @tryAny@.+--+-- Since 1.0.1+catchDeep :: (Exception e, NFData a, MonadBaseControl IO m) => m a -> (e -> m a) -> m a+catchDeep action onE = tryDeep action >>= either onE return+ -- | An extension to @catchAny@ which ensures that the return value is fully -- evaluated. See @tryAnyDeep@. --@@ -103,10 +112,23 @@ handleAnyDeep :: (NFData a, MonadBaseControl IO m) => (SomeException -> m a) -> m a -> m a handleAnyDeep = flip catchAnyDeep --- | An extension to @tryAny@ which ensures that the return value is fully--- evaluated. In other words, if you get a @Right@ response here, you can be+-- | an extension to @try@ which ensures that the return value is fully+-- evaluated. in other words, if you get a @right@ response here, you can be -- confident that using it will not result in another exception. --+-- Since 1.0.1+tryDeep :: (Exception e, NFData a, MonadBaseControl IO m)+ => m a+ -> m (Either e a)+tryDeep m = try $ do+ x <- m+ liftBase $ evaluate $!! x+++-- | an extension to @tryany@ which ensures that the return value is fully+-- evaluated. in other words, if you get a @right@ response here, you can be+-- confident that using it will not result in another exception.+-- -- Since 0.5.9 tryAnyDeep :: (NFData a, MonadBaseControl IO m) => m a@@ -147,4 +169,3 @@ -- Since 0.5.6 asIOException :: IOException -> IOException asIOException = id-
test/main.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# OPTIONS_GHC -fno-warn-orphans #-} import Test.Hspec@@ -27,6 +28,21 @@ threadDelay 50000 didFail <- readIORef failed liftIO $ didFail `shouldBe` (0 :: Int)++ it "catchDeep" $ do+ failed <- newIORef 0+ tid <- forkIO $ do+ catchDeep+ (threadDelay 10000 >> return (throw DummyExceptionInternal))+ (\(_::DummyExceptionInternal) -> writeIORef failed 1)+ threadDelay 20000+ writeIORef failed 2+ threadDelay 20000+ throwTo tid DummyException+ threadDelay 50000+ didFail <- readIORef failed+ liftIO $ didFail `shouldBe` (1 :: Int)+ it "tryAny" $ do failed <- newIORef False tid <- forkIO $ do@@ -37,6 +53,13 @@ threadDelay 50000 didFail <- readIORef failed liftIO $ didFail `shouldBe` False++ it "tryDeep" $ do+ eres <- tryDeep $ return $ throw DummyException+ case eres of+ Left DummyException -> return ()+ Right () -> error "Expected an exception" :: IO ()+ it "tryAnyDeep" $ do eres <- tryAnyDeep $ return $ throw DummyException case eres of@@ -49,4 +72,6 @@ deriving (Show, Typeable) instance Exception DummyException -+data DummyExceptionInternal = DummyExceptionInternal+ deriving (Show, Typeable)+instance Exception DummyExceptionInternal