safe-exceptions 0.1.1.0 → 0.1.2.0
raw patch · 4 files changed
+47/−2 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Control.Exception.Safe: [Handler] :: Handler m a
+ Control.Exception.Safe: Handler :: (e -> m a) -> Handler m a
+ Control.Exception.Safe: catches :: (MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a
+ Control.Exception.Safe: catchesAsync :: (MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a
+ Control.Exception.Safe: catchesDeep :: (MonadCatch m, MonadThrow m, MonadIO m, NFData a) => m a -> [Handler m a] -> m a
- Control.Exception.Safe: data Handler (m :: * -> *) a :: (* -> *) -> * -> *
+ Control.Exception.Safe: data Handler m a
- Control.Exception.Safe: displayException :: e -> String
+ Control.Exception.Safe: displayException :: Exception e => e -> String
- Control.Exception.Safe: fromException :: SomeException -> Maybe e
+ Control.Exception.Safe: fromException :: Exception e => SomeException -> Maybe e
- Control.Exception.Safe: mask :: ((forall a. m a -> m a) -> m b) -> m b
+ Control.Exception.Safe: mask :: MonadMask m => ((forall a. m a -> m a) -> m b) -> m b
- Control.Exception.Safe: toException :: e -> SomeException
+ Control.Exception.Safe: toException :: Exception e => e -> SomeException
- Control.Exception.Safe: uninterruptibleMask :: ((forall a. m a -> m a) -> m b) -> m b
+ Control.Exception.Safe: uninterruptibleMask :: MonadMask m => ((forall a. m a -> m a) -> m b) -> m b
Files
- ChangeLog.md +4/−0
- safe-exceptions.cabal +1/−1
- src/Control/Exception/Safe.hs +39/−1
- test/Control/Exception/SafeSpec.hs +3/−0
ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.1.2.0++* Added `catches` [#13](https://github.com/fpco/safe-exceptions/issues/13)+ ## 0.1.1.0 * Add missing `toSyncException` inside `impureThrow`
safe-exceptions.cabal view
@@ -1,5 +1,5 @@ name: safe-exceptions-version: 0.1.1.0+version: 0.1.2.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
@@ -34,6 +34,11 @@ , tryAnyDeep , tryAsync + , Handler(..)+ , catches+ , catchesDeep+ , catchesAsync+ -- * Cleanup (no recovery) , onException , bracket@@ -61,7 +66,6 @@ , C.catchIOError , C.handleIOError -- FIXME , C.tryIOError- , C.Handler (..) , Exception (..) , Typeable , SomeException (..)@@ -410,3 +414,37 @@ displayException :: Exception e => e -> String displayException = show #endif++-- | You need this when using 'catches'.+data Handler m a = forall e . (Exception e) => Handler (e -> m a)++-- | Same as upstream 'C.catches', but will not catch asynchronous+-- exceptions+--+-- @since 0.1.2.0+catches :: (C.MonadCatch m, C.MonadThrow m) => m a -> [Handler m a] -> m a+catches io handlers = io `catch` catchesHandler handlers++-- | Same as 'catches', but fully force evaluation of the result value+-- to find all impure exceptions.+--+-- @since 0.1.2.0+catchesDeep :: (C.MonadCatch m, C.MonadThrow m, MonadIO m, NFData a) => m a -> [Handler m a] -> m a+catchesDeep io handlers = evaluateDeep io `catch` catchesHandler handlers++-- | 'catches' without async exception safety+--+-- Generally it's better to avoid using this function since we do not want to+-- recover from async exceptions, see+-- <https://github.com/fpco/safe-exceptions#quickstart>+--+-- @since 0.1.2.0+catchesAsync :: (C.MonadCatch m, C.MonadThrow m) => m a -> [Handler m a] -> m a+catchesAsync io handlers = io `catchAsync` catchesHandler handlers++catchesHandler :: (C.MonadThrow m) => [Handler m a] -> SomeException -> m a+catchesHandler handlers e = foldr tryHandler (C.throwM e) handlers+ where tryHandler (Handler handler) res+ = case fromException e of+ Just e' -> handler e'+ Nothing -> res
test/Control/Exception/SafeSpec.hs view
@@ -105,3 +105,6 @@ res <- tryAnyDeep (return (impureThrow e)) -- deal with a missing NFData instance shouldBeSync $ either Left (\() -> Right undefined) res+ describe "catchesDeep" $ withAll $ \e _ -> do+ res <- return (impureThrow e) `catchesDeep` [Handler (\(_ :: SomeException) -> return ())]+ res `shouldBe` ()