annotated-exception 0.1.1.0 → 0.1.2.0
raw patch · 5 files changed
+167/−2 lines, 5 filesdep +unliftio-corePVP ok
version bump matches the API change (PVP)
Dependencies added: unliftio-core
API changes (from Hackage documentation)
+ Control.Exception.Annotated: catches :: MonadCatch m => m a -> [Handler m a] -> m a
+ Control.Exception.Annotated.UnliftIO: AnnotatedException :: [Annotation] -> exception -> AnnotatedException exception
+ Control.Exception.Annotated.UnliftIO: CallStackAnnotation :: [(String, SrcLoc)] -> CallStackAnnotation
+ Control.Exception.Annotated.UnliftIO: Handler :: (e -> m a) -> Handler (m :: Type -> Type) a
+ Control.Exception.Annotated.UnliftIO: SomeException :: e -> SomeException
+ Control.Exception.Annotated.UnliftIO: [Annotation] :: AnnC a => a -> Annotation
+ Control.Exception.Annotated.UnliftIO: [annotations] :: AnnotatedException exception -> [Annotation]
+ Control.Exception.Annotated.UnliftIO: [exception] :: AnnotatedException exception -> exception
+ Control.Exception.Annotated.UnliftIO: [unCallStackAnnotation] :: CallStackAnnotation -> [(String, SrcLoc)]
+ Control.Exception.Annotated.UnliftIO: addCallStackToException :: CallStack -> AnnotatedException exception -> AnnotatedException exception
+ Control.Exception.Annotated.UnliftIO: annotatedExceptionCallStack :: AnnotatedException exception -> Maybe CallStack
+ Control.Exception.Annotated.UnliftIO: catch :: forall e m a. (MonadUnliftIO m, Exception e) => m a -> (e -> m a) -> m a
+ Control.Exception.Annotated.UnliftIO: catches :: forall m a. MonadUnliftIO m => m a -> [Handler m a] -> m a
+ Control.Exception.Annotated.UnliftIO: check :: Exception e => AnnotatedException SomeException -> Maybe (AnnotatedException e)
+ Control.Exception.Annotated.UnliftIO: checkpoint :: forall m a. MonadUnliftIO m => Annotation -> m a -> m a
+ Control.Exception.Annotated.UnliftIO: checkpointCallStack :: (MonadCatch m, HasCallStack) => m a -> m a
+ Control.Exception.Annotated.UnliftIO: checkpointCallStackWith :: forall m a. (MonadUnliftIO m, HasCallStack) => [Annotation] -> m a -> m a
+ Control.Exception.Annotated.UnliftIO: checkpointMany :: forall m a. MonadUnliftIO m => [Annotation] -> m a -> m a
+ Control.Exception.Annotated.UnliftIO: class (Typeable e, Show e) => Exception e
+ Control.Exception.Annotated.UnliftIO: class Monad m => MonadIO (m :: Type -> Type)
+ Control.Exception.Annotated.UnliftIO: class MonadIO m => MonadUnliftIO (m :: Type -> Type)
+ Control.Exception.Annotated.UnliftIO: data AnnotatedException exception
+ Control.Exception.Annotated.UnliftIO: data Annotation
+ Control.Exception.Annotated.UnliftIO: data Handler (m :: Type -> Type) a
+ Control.Exception.Annotated.UnliftIO: data SomeException
+ Control.Exception.Annotated.UnliftIO: displayException :: Exception e => e -> String
+ Control.Exception.Annotated.UnliftIO: fromException :: Exception e => SomeException -> Maybe e
+ Control.Exception.Annotated.UnliftIO: hide :: Exception e => AnnotatedException e -> AnnotatedException SomeException
+ Control.Exception.Annotated.UnliftIO: liftIO :: MonadIO m => IO a -> m a
+ Control.Exception.Annotated.UnliftIO: new :: e -> AnnotatedException e
+ Control.Exception.Annotated.UnliftIO: newtype CallStackAnnotation
+ Control.Exception.Annotated.UnliftIO: throw :: forall e m a. (MonadIO m, Exception e) => e -> m a
+ Control.Exception.Annotated.UnliftIO: throwWithCallStack :: forall e m a. (MonadIO m, Exception e, HasCallStack) => e -> m a
+ Control.Exception.Annotated.UnliftIO: toException :: Exception e => e -> SomeException
+ Control.Exception.Annotated.UnliftIO: try :: forall e m a. (MonadUnliftIO m, Exception e) => m a -> m (Either e a)
+ Control.Exception.Annotated.UnliftIO: tryAnnotated :: forall e m a. (MonadUnliftIO m, Exception e) => m a -> m (Either (AnnotatedException e) a)
+ Control.Exception.Annotated.UnliftIO: withRunInIO :: MonadUnliftIO m => ((forall a. () => m a -> IO a) -> IO b) -> m b
Files
- ChangeLog.md +7/−0
- annotated-exception.cabal +4/−1
- src/Control/Exception/Annotated.hs +2/−1
- src/Control/Exception/Annotated/UnliftIO.hs +146/−0
- test/Control/Exception/AnnotatedSpec.hs +8/−0
ChangeLog.md view
@@ -2,6 +2,13 @@ ## Unreleased changes +## 0.1.2.0++- [#6](https://github.com/parsonsmatt/annotated-exception/pull/6)+ - Add `Control.Exception.Annotated.UnliftIO` that uses `MonadUnliftIO`+ instead of `MonadCatch` and `MonadThrow`.+ - Actually expose `catches`+ ## 0.1.1.0 - [#4](https://github.com/parsonsmatt/annotated-exception/pull/4)
annotated-exception.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: annotated-exception-version: 0.1.1.0+version: 0.1.2.0 synopsis: Exceptions, with checkpoints and context. description: Please see the README on Github at <https://github.com/parsonsmatt/annotated-exception#readme> category: Control@@ -28,6 +28,7 @@ library exposed-modules: Control.Exception.Annotated+ Control.Exception.Annotated.UnliftIO Data.Annotation other-modules: Paths_annotated_exception@@ -39,6 +40,7 @@ , containers , safe-exceptions , text+ , unliftio-core default-language: Haskell2010 test-suite annotated-exception-test@@ -60,4 +62,5 @@ , hspec , safe-exceptions , text+ , unliftio-core default-language: Haskell2010
src/Control/Exception/Annotated.hs view
@@ -37,6 +37,7 @@ , checkpointCallStackWith -- * Handling Exceptions , catch+ , catches , tryAnnotated , try @@ -183,7 +184,7 @@ -- | Like 'Safe.catches', but this function enhance the provided 'Handler's -- to "see through" any 'AnnotatedException's. ----- @since 0.1.1.0+-- @since 0.1.2.0 catches :: (MonadCatch m) => m a -> [Handler m a] -> m a catches action handlers = Safe.catches action (mkAnnotatedHandlers handlers)
+ src/Control/Exception/Annotated/UnliftIO.hs view
@@ -0,0 +1,146 @@+{-# language ExplicitForAll #-}++-- | This module presents the same interface as+-- "Control.Exception.Annotated", but uses 'MonadUnliftIO' instead of+-- 'MonadCatch' or 'MonadThrow'.+--+-- @since 0.1.2.0+module Control.Exception.Annotated.UnliftIO+ ( -- * The Main Type+ AnnotatedException(..)+ , new+ , throwWithCallStack+ -- * Annotating Exceptions+ , checkpoint+ , checkpointMany+ , checkpointCallStack+ , checkpointCallStackWith+ -- * Handling Exceptions+ , catch+ , catches+ , tryAnnotated+ , try++ -- * Manipulating Annotated Exceptions+ , check+ , hide+ , annotatedExceptionCallStack+ , addCallStackToException++ -- * Re-exports from "Data.Annotation"+ , Annotation(..)+ , CallStackAnnotation(..)+ -- * Re-exports from "Control.Exception.Safe"+ , Exception(..)+ , Safe.SomeException(..)+ , throw+ , Handler (..)+ , MonadIO(..)+ , MonadUnliftIO(..)+ ) where++import Control.Exception.Annotated hiding+ ( catch+ , catches+ , checkpoint+ , checkpointCallStackWith+ , checkpointMany+ , throw+ , throwWithCallStack+ , try+ , tryAnnotated+ )+import qualified Control.Exception.Annotated as Catch+import qualified Control.Exception.Safe as Safe+import Control.Monad.IO.Unlift+import GHC.Stack++-- | Like 'Catch.throwWithCallStack', but uses 'MonadIO' instead of+-- 'MonadThrow'.+--+-- @since 0.1.2.0+throwWithCallStack+ :: forall e m a. (MonadIO m, Exception e, HasCallStack)+ => e -> m a+throwWithCallStack = liftIO . Catch.throwWithCallStack++-- | Like 'Catch.throw', but uses 'MonadIO' instead of 'MonadThrow'.+--+-- @since 0.1.2.0+throw :: forall e m a. (MonadIO m, Exception e) => e -> m a+throw = liftIO . Catch.throw++-- | Like 'Catch.checkpoint', but uses 'MonadUnliftIO' instead of 'MonadCatch'.+--+-- @since 0.1.2.0+checkpoint :: forall m a. (MonadUnliftIO m) => Annotation -> m a -> m a+checkpoint ann action = withRunInIO $ \runInIO ->+ liftIO $ Catch.checkpoint ann (runInIO action)++-- | Like 'Catch.checkpointMany', but uses 'MonadUnliftIO' instead of+-- 'MonadCatch'.+--+-- @since 0.1.2.0+checkpointMany :: forall m a. (MonadUnliftIO m) => [Annotation] -> m a -> m a+checkpointMany anns action =+ withRunInIO $ \runInIO ->+ liftIO $ Catch.checkpointMany anns (runInIO action)++-- | Like 'Catch.checkpointCallStackWith', but uses 'MonadUnliftIO' instead of+-- 'MonadCatch'.+--+-- @since 0.1.2.0+checkpointCallStackWith+ :: forall m a. (MonadUnliftIO m, HasCallStack)+ => [Annotation] -> m a -> m a+checkpointCallStackWith anns action =+ withRunInIO $ \runInIO ->+ liftIO $ Catch.checkpointCallStackWith anns (runInIO action)++-- | Like 'Catch.catch', but uses 'MonadUnliftIO' instead of 'MonadCatch'.+--+-- @since 0.1.2.0+catch+ :: forall e m a. (MonadUnliftIO m, Exception e)+ => m a+ -> (e -> m a)+ -> m a+catch action handler =+ withRunInIO $ \runInIO ->+ liftIO $ Catch.catch (runInIO action) (\e -> runInIO $ handler e)++-- | Like 'Catch.tryAnnotated' but uses 'MonadUnliftIO' instead of 'MonadCatch'.+--+-- @since 0.1.2.0+tryAnnotated+ :: forall e m a. (MonadUnliftIO m, Exception e)+ => m a+ -> m (Either (AnnotatedException e) a)+tryAnnotated action =+ withRunInIO $ \runInIO ->+ liftIO $ Catch.tryAnnotated (runInIO action)++-- | Like 'Catch.try' but uses 'MonadUnliftIO' instead of 'MonadCatch'.+--+-- @since 0.1.2.0+try+ :: forall e m a. (MonadUnliftIO m, Exception e)+ => m a+ -> m (Either e a)+try action =+ withRunInIO $ \runInIO ->+ liftIO $ Catch.try (runInIO action)++-- | Like 'Catch.catches', bt uses 'MonadUnliftIO' instead of 'MonadCatch'.+--+-- @since 0.1.2.0+catches+ :: forall m a. MonadUnliftIO m+ => m a+ -> [Handler m a]+ -> m a+catches action handlers =+ withRunInIO $ \runInIO -> do+ let f (Handler k) = Handler (\e -> runInIO (k e))+ liftIO $ catches (runInIO action) (map f handlers)+ where
test/Control/Exception/AnnotatedSpec.hs view
@@ -114,6 +114,14 @@ exn `shouldBe` TestException action `shouldThrow` (== new TestException) + describe "catches" $ do+ it "is exported" $ do+ let+ _x :: IO a -> [Handler IO a] -> IO a+ _x = catches+ pass++ describe "checkpoint" $ do it "adds annotations" $ do Left exn <- try (checkpoint "Here" (throw TestException))