-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | The canonical error type -- -- A canonical Error type, which provides a way to turn an error -- string into an Error, add context to an Error, and -- pretty print the Error for displaying it to users. @package error @version 0.2.1.2 module Data.Error -- | The canonical Error type. -- -- It can be -- --
-- addContext "Trying to open config file" -- $ newError "file not found: ./foo" ---- -- This way, when a user see the error, they will understand better what -- happened: -- --
-- "Trying to open config file: file not found: ./foo" ---- -- See prettyError. addContext :: Text -> Error -> Error -- | Pretty print the error. -- -- It will print all context messages, starting with the outermost. -- -- Example: -- --
-- >>> prettyError $ newError "file not found: ./foo" -- "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
-- | Return the value from a potentially failing computation.
--
-- Abort with the error message if it was an error.
--
-- The text message is added to the Error as additional context
-- before aborting.
--
-- Panics: if Error
--
-- Example:
--
-- -- >>> expectError "something bad happened" $ Left (newError "oh no!") -- *** Exception: something bad happened: oh no! -- ... ---- --
-- >>> expectError "something bad happened" $ Right 42 -- 42 --expectError :: HasCallStack => Text -> Either Error p -> p -- | Return the value from a potentially failing computation. -- -- Abort with the Errors message if it was a Left. -- -- Panics: if Error -- -- Example: -- --
-- >>> unwrapError $ Left (newError "oh no!") -- *** Exception: oh no! -- ... ---- --
-- >>> unwrapError $ Right 42 -- 42 --unwrapError :: HasCallStack => Either Error a -> a -- | Like expectError, but instead of using error, it will -- throwIO the pretty-printed error. -- -- The advantage over expectError is that it crashes immediately, -- and not just when the Either is forced, leading to a -- deterministic immediate abortion of your IO code (but no stack -- trace can be produced at the moment!). -- -- Throws opaque Exception: if Error -- -- Example: -- --
-- >>> expectIOError "something bad happened" $ Left (newError "oh no!") -- *** Exception: something bad happened: oh no! ---- -- Important: Error itself does not implement -- Exception to discourage the exception workflow. The -- Exception thrown is private to this module and thus can’t be -- “caught” in a typed manner. If you use this function, you either have -- to catch SomeException, or it will bubble up and lead to your -- program crashing. expectIOError :: Text -> Either Error a -> IO a -- | Like unwrapError, but instead of using error, it will -- throwIO the pretty-printed error. -- -- The advantage over unwrapError is that it crashes immediately, -- and not just when the Either is forced, leading to a -- deterministic immediate abortion of your IO code (but no stack -- trace can be produced at the moment!). -- -- Throws opaque Exception: if Error -- -- Example: -- --
-- >>> unwrapIOError $ Left (newError "oh no!") -- *** Exception: oh no! ---- -- Important: Error itself does not implement -- Exception to discourage the exception workflow. The -- Exception thrown is private to this module and thus can’t be -- “caught” in a typed manner. If you use this function, you either have -- to catch SomeException, or it will bubble up and lead to your -- program crashing. unwrapIOError :: Either Error a -> IO a -- | Catch any IOExceptions 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 without any context. -- --
-- >>> ifIOError "could not open file" (Control.Exception.throwIO (userError "oh noes!")) -- Left (Error ["could not open file","user error (oh noes!)"]) ---- -- It can then be handled like a normal Error. -- -- The function lends itself to piping with (&): -- --
-- >>> Control.Exception.throwIO (userError "oh noes!") & ifIOError "could not open file" -- Left (Error ["could not open file","user error (oh noes!)"]) ---- -- and if you just want to annotate the error and directly throw it -- again: -- --
-- >>> Control.Exception.throwIO (userError "oh noes!") & ifIOError "could not open file" >>= unwrapIOError -- *** Exception: could not open file: user error (oh noes!) --ifIOError :: Text -> IO a -> IO (Either Error a) -- | Catch any Exceptions 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 without any context. -- -- Use TypeApplications to specify the Exception you want -- to catch. -- --
-- >>> :set -XTypeApplications -- -- >>> ifError @Exc.ArithException "arithmetic exception" (putStr $ show $ 1 Data.Ratio.% 0) -- Left (Error ["arithmetic exception","Ratio has zero denominator"]) ---- -- It can then be handled like a normal Error. -- -- The function lends itself to piping with (&): -- --
-- >>> (putStr $ show $ 1 Data.Ratio.% 0) & ifError @Exc.ArithException "arithmetic exception" -- Left (Error ["arithmetic exception","Ratio has zero denominator"]) ---- -- 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) instance GHC.Show.Show Data.Error.Error instance GHC.Show.Show Data.Error.ErrorException instance GHC.Exception.Type.Exception Data.Error.ErrorException