-- 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 -- -- data Error -- | Create an ad-hoc Error from an error message. newError :: Text -> Error -- | 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 -- | 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 -- | 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, and describe why you wanted to open the file in the -- first place: -- --
--   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