error 0.2.1.2 → 0.3.0.0
raw patch · 3 files changed
+35/−14 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Error: addContext :: Text -> Error -> Error
+ Data.Error: errorContext :: Text -> Error -> Error
+ Data.Error: instance Data.String.IsString Data.Error.Error
Files
- CHANGELOG.md +11/−0
- error.cabal +1/−1
- src/Data/Error.hs +23/−13
CHANGELOG.md view
@@ -1,5 +1,16 @@ # Revision history for error +## 0.3.0.0 -- 2022-02-16++* Add `IsString` instance for `Error`.++* Breaking: Rename `addContext` to `errorContext`.++ Since `Data.Error` is expected to be imported unqualified,+ `addContext` was not super obviously related to error handling.+ `errorContext` is a lot clearer.+ This is hopefully the last big breaking change before `1.0`.+ ## 0.2.1.2 -- 2021-11-15 * Fix doctests.
error.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: error-version: 0.2.1.2+version: 0.3.0.0 synopsis: The canonical error type
src/Data/Error.hs view
@@ -12,11 +12,11 @@ -- *** From 'Show' and 'Exception' -- | These two functions can be helpful, but consider that they don’t always provide very user-friendly error messages.- -- It is recommended that you use `addContext` to improve the messages generated by 'showToError' and 'exceptionToError'.+ -- It is recommended that you use `errorContext` to improve the messages generated by 'showToError' and 'exceptionToError'. showToError, exceptionToError, -- * Adding context- addContext,+ errorContext, -- * Pretty printing prettyError, -- * Unsafe unwrapping@@ -51,13 +51,14 @@ import Control.Exception (Exception (displayException)) import qualified Control.Exception as Exc import Data.Bifunctor (first)+import Data.String (IsString (fromString)) -- | The canonical @Error@ type. -- -- It can be -- -- * created from a human-readable error message ('newError')--- * more semantic context can be added to an existing @Error@ ('addContext')+-- * more semantic context can be added to an existing @Error@ ('errorContext') -- * pretty-printed (`prettyError`) newtype Error = Error [Text] @@ -66,6 +67,15 @@ -- If you want to display an error, use 'prettyError' instead. deriving instance Show Error +-- | This makes it possible to treat any literal string as 'Error' (with @OverloadedStrings@ enabled).+--+-- >>> prettyError $ errorContext "oops" $ "my Error"+-- "oops: my Error"+--+-- No 'newError' necessary!+instance IsString Error where+ fromString = newError . Text.pack+ -- | Create an ad-hoc 'Error' from an error message. newError :: Text -> Error newError msg = Error [msg]@@ -90,11 +100,11 @@ -- | Add a higher-level context to an 'Error'. -- -- For example, your code hits a “file not found” I/O exception.--- Instead of propagating it unseen, you catch it and annotate it with 'addContext',+-- Instead of propagating it unseen, you catch it and annotate it with 'errorContext', -- and describe why you wanted to open the file in the first place: -- -- @--- addContext "Trying to open config file"+-- errorContext "Trying to open config file" -- $ newError "file not found: ./foo" -- @ --@@ -105,8 +115,8 @@ -- @ -- -- See 'prettyError'.-addContext :: Text -> Error -> Error-addContext e (Error es) = Error $ e : es+errorContext :: Text -> Error -> Error+errorContext e (Error es) = Error $ e : es -- | Pretty print the error. --@@ -119,7 +129,7 @@ -- -- >>> :{ -- prettyError--- $ addContext "Trying to open config file"+-- $ errorContext "Trying to open config file" -- $ newError "file not found: ./foo" -- :} -- "Trying to open config file: file not found: ./foo"@@ -166,7 +176,7 @@ Left err -> error ( err- & addContext context+ & errorContext context & prettyError & Text.unpack )@@ -223,13 +233,13 @@ -- your program crashing. expectIOError :: Text -> Either Error a -> IO a expectIOError context = \case- Left err -> Exc.throwIO $ ErrorException (addContext context err)+ Left err -> Exc.throwIO $ ErrorException (errorContext context err) Right a -> pure a -- | Catch any 'Exc.IOException's thrown by an @IO a@ as @Either Error a@. -- -- The IOException is converted to an error with 'exceptionToError', and the given message--- is added with 'addContext'. This prevents the common pattern of bubbling up exceptions+-- is added with 'errorContext'. This prevents the common pattern of bubbling up exceptions -- without any context. -- -- >>> ifIOError "could not open file" (Control.Exception.throwIO (userError "oh noes!"))@@ -252,7 +262,7 @@ -- | Catch any 'Exc.Exception's thrown by an @IO a@ as @Either Error a@. -- -- The IOException is converted to an error with 'exceptionToError', and the given message--- is added with 'addContext'. This prevents the common pattern of bubbling up exceptions+-- is added with 'errorContext'. This prevents the common pattern of bubbling up exceptions -- without any context. -- -- Use @TypeApplications@ to specify the 'Exception' you want to catch.@@ -271,4 +281,4 @@ -- Bear in mind that pure exceptions are only raised when the resulting code is forced -- (thus the @putStrLn $ show@ in the above example). ifError :: forall exc a. (Exception exc) => Text -> IO a -> IO (Either Error a)-ifError context io = first (addContext context . exceptionToError) <$> Exc.try @exc io+ifError context io = first (errorContext context . exceptionToError) <$> Exc.try @exc io