packages feed

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 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` ()