packages feed

error 0.1.0.0 → 0.1.1.0

raw patch · 4 files changed

+85/−32 lines, 4 filesdep +doctestdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: doctest

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Error: exceptionToError :: Exception exc => exc -> Error
+ Data.Error: showToError :: Show a => a -> Error
- Data.Error: expectError :: Text -> Either Error p -> p
+ Data.Error: expectError :: HasCallStack => Text -> Either Error p -> p
- Data.Error: unwrapError :: Either Error p -> p
+ Data.Error: unwrapError :: HasCallStack => Either Error p -> p

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for error +## 0.1.1.0 -- 2021-10-28++* Add `HasCallStack` to `expectError` and `unwrapError`.+* Add `showToError` and `exceptionToError`.+* Improved documentation of existing functions.+ ## 0.1.0.0 -- 2021-06-26  * Initial version. More or less feature complete, 
error.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               error-version:            0.1.0.0+version:            0.1.1.0  synopsis: The canonical error type @@ -38,6 +38,16 @@      -- LANGUAGE extensions used by modules in this package.     -- other-extensions:++test-suite doctest+    type:             exitcode-stdio-1.0+    hs-source-dirs:   test+    main-is:          DocTest.hs+    default-language: Haskell2010+    build-depends:+        base+      , doctest+  source-repository head   type: git
src/Data/Error.hs view
@@ -1,17 +1,39 @@ {-# LANGUAGE OverloadedStrings #-} module Data.Error   ( Error,+    -- * Error creation     newError,+    -- *** 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'.+    showToError,+    exceptionToError,+    -- * Adding context     addContext,+    -- * Pretty printing     prettyError,-    unwrapError,+    -- * Unsafe unwrapping++    -- | Sometimes you want to assure that an 'Error' could not have happened at runtime,+    -- even though there is the possibility in the types.+    -- In that case you can use 'expectError'/'unwrapError'.+    -- They will panic at runtime if there was an error.+    --+    -- 'expectError' should usually be preffered, since it adds a context message.+    --+    -- These are modelled after @<https://doc.rust-lang.org/std/result/enum.Result.html#method.expect Result::expect()>@+    -- and @<https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap Result::unwrap()>@ in the rust stdlib.     expectError,+    unwrapError,   ) where  import Data.Function ((&)) import Data.Text (Text) import qualified Data.Text as Text+import GHC.Stack (HasCallStack)+import Control.Exception (Exception (displayException))  -- | The canonical @Error@ type. --@@ -26,6 +48,23 @@ newError :: Text -> Error newError msg = Error [msg] +-- | Create an error from a `Show` type.+--+-- If your type implements 'Exception', it is usually better to use 'exceptionToError' instead.+-- Strings produced by 'show' are usually not very user-friendly.+--+-- Note: goes via `String`, so not efficient.+showToError :: Show a => a -> Error+showToError = newError . Text.pack . show++-- | Create an error from an 'Exception' type.+--+-- The default implementation of 'displayException' is 'show', so the same user-friendliness problems of 'showToError' apply.+--+-- Note: goes via `String`, so not efficient.+exceptionToError :: Exception exc => exc -> Error+exceptionToError = newError . Text.pack . displayException+ -- | Add a higher-level context to an 'Error'. -- -- For example, your code hits a “file not found” I/O exception.@@ -53,17 +92,15 @@ -- -- Example: ----- @--- prettyError $ newError "file not found: ./foo"------ ==> "file not found: ./foo"------ prettyError---   $ addContext "Trying to open config file"---     $ newError "file not found: ./foo"+-- >>> prettyError $ newError "file not found: ./foo"+-- "file not found: ./foo" ----- ==> "Trying to open config file: file not found: ./foo"--- @+-- >>> :{+--   prettyError+--     $ addContext "Trying to open config file"+--       $ newError "file not found: ./foo"+-- :}+-- "Trying to open config file: file not found: ./foo" prettyError :: Error -> Text prettyError (Error es) = Text.intercalate ": " es @@ -71,20 +108,17 @@ -- -- Abort with the 'Error's message if it was a 'Left'. ----- Panic: if Error+-- __Panics__: if Error -- -- Example: ----- @--- unwrapError $ Left (newError "oh no!")------ ==> *** Exception: oh no!------ unwrapError $ Right 42+-- >>> unwrapError $ Left (newError "oh no!")+-- *** Exception: oh no!+-- ... ----- ==> 42--- @-unwrapError :: Either Error p -> p+-- >>> unwrapError $ Right 42+-- 42+unwrapError :: HasCallStack => Either Error p -> p unwrapError e = case e of   Left err -> error (prettyError err & Text.unpack)   Right a -> a@@ -95,20 +129,17 @@ -- -- The text message is added to the 'Error' as additional context before aborting. ----- Panic: if Error+-- __Panics__: if Error -- -- Example: ----- @--- exceptError "something bad happened" $ Left (newError "oh no!")------ ==> *** Exception: something bad happened: oh no!------ exceptError $ Right 42+-- >>> expectError "something bad happened" $ Left (newError "oh no!")+-- *** Exception: something bad happened: oh no!+-- ... ----- ==> 42--- @-expectError :: Text -> Either Error p -> p+-- >>> expectError "something bad happened" $ Right 42+-- 42+expectError :: HasCallStack => Text -> Either Error p -> p expectError context e = case e of   Left err ->     error
+ test/DocTest.hs view
@@ -0,0 +1,6 @@+module Main where++import Test.DocTest++main :: IO ()+main = doctest [ "-XOverloadedStrings", "src" ]