errors 2.1.3 → 2.2.0
raw patch · 6 files changed
+47/−16 lines, 6 filesdep +exceptionsdep +textdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: exceptions, text
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Control.Error.Util: handleExceptT :: (Exception e, Functor m, MonadCatch m) => (e -> x) -> m a -> ExceptT x m a
- Control.Error.Script: scriptIO :: (MonadIO m) => IO a -> ExceptT String m a
+ Control.Error.Script: scriptIO :: (MonadIO m) => IO a -> ExceptT Text m a
- Control.Error.Script: type Script = ExceptT String IO
+ Control.Error.Script: type Script = ExceptT Text IO
- Control.Error.Util: err :: String -> IO ()
+ Control.Error.Util: err :: Text -> IO ()
- Control.Error.Util: errLn :: String -> IO ()
+ Control.Error.Util: errLn :: Text -> IO ()
Files
- CHANGELOG.md +13/−0
- Control/Error.hs +1/−1
- Control/Error/Script.hs +14/−7
- Control/Error/Util.hs +15/−6
- Data/EitherR.hs +1/−1
- errors.cabal +3/−1
CHANGELOG.md view
@@ -1,3 +1,16 @@+# 2.2.0++* BREAKING CHANGE: Use `Text` instead of `String`+* Add `handleExceptT`++# 2.1.3++* Support older versions of `ghc`++# 2.1.2++* Increase upper bound on `transformers` dependency+ # 2.1.1 * Increase upper bound on `transformers-compat`
Control/Error.hs view
@@ -10,7 +10,7 @@ 'EitherT', and 'MonadPlus' variations on total functions * "Control.Error.Script": Support for simple scripts that catch all errors- and transform them to 'String's+ and transform them to 'Text' * "Control.Error.Util": Utility functions and conversions between common error-handling types
Control/Error/Script.hs view
@@ -1,5 +1,7 @@+{-# LANGUAGE OverloadedStrings #-}+ {-|- Use this module if you like to write simple scripts with 'String'-based+ Use this module if you like to write simple scripts with 'Text'-based errors, but you prefer to use 'ExceptT' to handle errors rather than @Control.Exception@. @@ -24,6 +26,8 @@ import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT) import Control.Error.Util (errLn) import Data.EitherR (fmapL)+import Data.Monoid ((<>))+import Data.Text (Text) import System.Environment (getProgName) import System.Exit (exitFailure) @@ -31,9 +35,11 @@ import Control.Monad.Trans.Class (lift) import System.IO (stderr) --- | An 'IO' action that can fail with a 'String' error message-type Script = ExceptT String IO+import qualified Data.Text +-- | An 'IO' action that can fail with a 'Text' error message+type Script = ExceptT Text IO+ {-| Runs the 'Script' monad Prints the first error to 'stderr' and exits with 'exitFailure'@@ -43,17 +49,18 @@ e <- runExceptT s case e of Left e -> do- errLn =<< liftM (++ ": " ++ e) getProgName+ let adapt str = Data.Text.pack str <> ": " <> e+ errLn =<< liftM adapt getProgName exitFailure Right a -> return a {-| 'scriptIO' resembles 'lift', except it catches all exceptions and converts- them to 'String's.+ them to 'Text' Note that 'scriptIO' is compatible with the 'Script' monad. -}-scriptIO :: (MonadIO m) => IO a -> ExceptT String m a+scriptIO :: (MonadIO m) => IO a -> ExceptT Text m a scriptIO = ExceptT . liftIO- . liftM (fmapL show)+ . liftM (fmapL (Data.Text.pack . show)) . (try :: IO a -> IO (Either SomeException a))
Control/Error/Util.hs view
@@ -47,23 +47,27 @@ -- * Exceptions tryIO,+ handleExceptT, syncIO ) where import Control.Applicative (Applicative, pure, (<$>))-import Control.Exception (Handler(..), IOException, SomeException)+import Control.Exception (Handler(..), IOException, SomeException, Exception) import Control.Monad (liftM)+import Control.Monad.Catch (MonadCatch, try) import Control.Monad.IO.Class (MonadIO(liftIO))-import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT)+import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT, withExceptT) import Control.Monad.Trans.Maybe (MaybeT(MaybeT), runMaybeT) import Data.Dynamic (Dynamic) import Data.Monoid (Monoid(mempty, mappend)) import Data.Maybe (fromMaybe)+import Data.Text (Text) import System.Exit (ExitCode) import System.IO (hPutStr, hPutStrLn, stderr) import UnexceptionalIO (UIO, Unexceptional) import qualified Control.Exception as Exception+import qualified Data.Text.IO import qualified UnexceptionalIO as UIO -- | Fold an 'ExceptT' by providing one continuation for each constructor@@ -228,16 +232,21 @@ fmapRT = liftM -- | Write a string to standard error-err :: String -> IO ()-err = hPutStr stderr+err :: Text -> IO ()+err = Data.Text.IO.hPutStr stderr -- | Write a string with a newline to standard error-errLn :: String -> IO ()-errLn = hPutStrLn stderr+errLn :: Text -> IO ()+errLn = Data.Text.IO.hPutStrLn stderr -- | Catch 'IOException's and convert them to the 'ExceptT' monad tryIO :: MonadIO m => IO a -> ExceptT IOException m a tryIO = ExceptT . liftIO . Exception.try++-- | Run a monad action which may throw an exception in the `ExceptT` monad+handleExceptT :: (Exception e, Functor m, MonadCatch m) => (e -> x) -> m a -> ExceptT x m a+handleExceptT handler = bimapExceptT handler id . ExceptT . try+ {-| Catch all exceptions, except for asynchronous exceptions found in @base@ and convert them to the 'ExceptT' monad
Data/EitherR.hs view
@@ -173,7 +173,7 @@ succeedT :: (Monad m) => r -> ExceptRT r m e succeedT r = ExceptRT (return r) --- | 'catchT' with the arguments flipped+-- | 'catchE' with the arguments flipped handleE :: (Monad m) => (a -> ExceptT b m r) -> ExceptT a m r -> ExceptT b m r handleE = flip catchE
errors.cabal view
@@ -1,5 +1,5 @@ Name: errors-Version: 2.1.3+Version: 2.2.0 Cabal-Version: >=1.8.0.2 Build-Type: Simple Tested-With: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2, GHC == 8.0.1@@ -25,6 +25,8 @@ Library Build-Depends: base >= 4 && < 5 ,+ exceptions >= 0.6 && < 0.9,+ text < 1.3, transformers >= 0.2 && < 0.6, transformers-compat >= 0.4 && < 0.6, unexceptionalio >= 0.3 && < 0.4