packages feed

safe-exceptions 0.1.3.0 → 0.1.4.0

raw patch · 4 files changed

+45/−1 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Exception.Safe: catchJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
+ Control.Exception.Safe: handleJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
+ Control.Exception.Safe: tryJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.1.4.0++* Add `catchJust`, `handleJust`, and `tryJust`+ ## 0.1.3.0  * Add `catchIO`, `handleIO`, and `tryIO`
safe-exceptions.cabal view
@@ -1,5 +1,5 @@ name:                safe-exceptions-version:             0.1.3.0+version:             0.1.4.0 synopsis:            Safe, consistent, and easy exception handling description:         Please see README.md homepage:            https://github.com/fpco/safe-exceptions#readme
src/Control/Exception/Safe.hs view
@@ -22,6 +22,7 @@     , catchDeep     , catchAnyDeep     , catchAsync+    , catchJust      , handle     , handleIO@@ -29,6 +30,7 @@     , handleDeep     , handleAnyDeep     , handleAsync+    , handleJust      , try     , tryIO@@ -36,6 +38,7 @@     , tryDeep     , tryAnyDeep     , tryAsync+    , tryJust      , Handler(..)     , catches@@ -179,6 +182,14 @@ catchAsync :: (C.MonadCatch m, Exception e) => m a -> (e -> m a) -> m a catchAsync = C.catch +-- | 'catchJust' is like 'catch' but it takes an extra argument which+-- is an exception predicate, a function which selects which type of+-- exceptions we're interested in.+--+-- @since 0.1.4.0+catchJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a+catchJust f a b = a `catch` \e -> maybe (throwM e) b $ f e+ -- | Flipped version of 'catch' -- -- @since 0.1.0.0@@ -220,6 +231,12 @@ handleAsync :: (C.MonadCatch m, Exception e) => (e -> m a) -> m a -> m a handleAsync = C.handle +-- | Flipped 'catchJust'.+--+-- @since 0.1.4.0+handleJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a+handleJust f = flip (catchJust f)+ -- | Same as upstream 'C.try', but will not catch asynchronous -- exceptions --@@ -261,6 +278,13 @@ -- @since 0.1.0.0 tryAsync :: (C.MonadCatch m, E.Exception e) => m a -> m (Either e a) tryAsync = C.try++-- | A variant of 'try' that takes an exception predicate to select+-- which exceptions are caught.+--+-- @since 0.1.4.0+tryJust :: (C.MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)+tryJust f a = catch (Right `liftM` a) (\e -> maybe (throwM e) (return . Left) (f e))  -- | Async safe version of 'E.onException' --
test/Control/Exception/SafeSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE ScopedTypeVariables #-} module Control.Exception.SafeSpec (spec) where @@ -6,11 +7,16 @@ import qualified Control.Exception as E import Control.Exception.Safe import Control.Monad (forever)+import Data.Typeable (Typeable) import Data.Void (Void, absurd) import System.IO.Unsafe (unsafePerformIO) import System.Timeout (timeout) import Test.Hspec +newtype ExceptionPred = ExceptionPred { getExceptionPred :: Maybe () } deriving (Show, Eq, Typeable)++instance Exception ExceptionPred+ -- | Ugly hack needed because the underlying type is not exported timeoutException :: SomeException timeoutException =@@ -108,3 +114,13 @@         describe "catchesDeep" $ withAll $ \e _ -> do             res <- return (impureThrow e) `catchesDeep` [Handler (\(_ :: SomeException) -> return ())]             res `shouldBe` ()++    describe "catchJust" $ do+      it "catches a selected exception" $ do+        res <- catchJust getExceptionPred (throw (ExceptionPred (Just ()))) (return . Just)+        res `shouldBe` Just ()++      it "re-raises a selection that is passed on" $ do+        let ex = ExceptionPred Nothing+        res <- try (catchJust getExceptionPred (throw ex) (return . Just))+        res `shouldBe` Left ex