-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Safe, consistent, and easy exception handling -- -- Please see README.md @package safe-exceptions @version 0.1.7.4 -- | Please see the README.md file in the safe-exceptions repo for -- information on how to use this module. Relevant links: -- -- module Control.Exception.Safe -- | Synchronously throw the given exception throw :: () => (MonadThrow m, Exception e) => e -> m a -- | Synonym for throw throwIO :: () => (MonadThrow m, Exception e) => e -> m a -- | Synonym for throw throwM :: () => (MonadThrow m, Exception e) => e -> m a -- | A convenience function for throwing a user error. This is useful for -- cases where it would be too high a burden to define your own exception -- type. -- -- This throws an exception of type StringException. When GHC -- supports it (base 4.9 and GHC 8.0 and onward), it includes a call -- stack. throwString :: (MonadThrow m, HasCallStack) => String -> m a -- | Exception type thrown by throwString. -- -- Note that the second field of the data constructor depends on GHC/base -- version. For base 4.9 and GHC 8.0 and later, the second field is a -- call stack. Previous versions of GHC and base do not support call -- stacks, and the field is simply unit (provided to make pattern -- matching across GHC versions easier). data StringException StringException :: String -> CallStack -> StringException -- | Throw an asynchronous exception to another thread. -- -- Synchronously typed exceptions will be wrapped into an -- AsyncExceptionWrapper, see -- https://github.com/fpco/safe-exceptions#determining-sync-vs-async -- -- It's usually a better idea to use the async package, see -- https://github.com/fpco/safe-exceptions#quickstart throwTo :: (Exception e, MonadIO m) => ThreadId -> e -> m () -- | Generate a pure value which, when forced, will synchronously throw the -- given exception -- -- Generally it's better to avoid using this function and instead use -- throw, see -- https://github.com/fpco/safe-exceptions#quickstart impureThrow :: () => Exception e => e -> a -- | Same as upstream catch, but will not catch asynchronous -- exceptions catch :: () => (MonadCatch m, Exception e) => m a -> (e -> m a) -> m a -- | catch specialized to only catching IOExceptions catchIO :: () => MonadCatch m => m a -> (IOException -> m a) -> m a -- | catch specialized to catch all synchronous exception catchAny :: () => MonadCatch m => m a -> (SomeException -> m a) -> m a -- | Same as catch, but fully force evaluation of the result value -- to find all impure exceptions. catchDeep :: () => (MonadCatch m, MonadIO m, Exception e, NFData a) => m a -> (e -> m a) -> m a -- | catchDeep specialized to catch all synchronous exception catchAnyDeep :: () => (MonadCatch m, MonadIO m, NFData a) => m a -> (SomeException -> m a) -> m a -- | catch without async exception safety -- -- Generally it's better to avoid using this function since we do not -- want to recover from async exceptions, see -- https://github.com/fpco/safe-exceptions#quickstart catchAsync :: () => (MonadCatch m, Exception e) => m a -> (e -> m a) -> m a -- | catchJust is like catch but it takes an extra argument -- which is an exception predicate, a function which selects which type -- of exceptions we're interested in. catchJust :: () => (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a -- | Flipped version of catch handle :: () => (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a -- | handle specialized to only catching IOExceptions handleIO :: () => MonadCatch m => (IOException -> m a) -> m a -> m a -- | Flipped version of catchAny handleAny :: () => MonadCatch m => (SomeException -> m a) -> m a -> m a -- | Flipped version of catchDeep handleDeep :: () => (MonadCatch m, Exception e, MonadIO m, NFData a) => (e -> m a) -> m a -> m a -- | Flipped version of catchAnyDeep handleAnyDeep :: () => (MonadCatch m, MonadIO m, NFData a) => (SomeException -> m a) -> m a -> m a -- | Flipped version of catchAsync -- -- Generally it's better to avoid using this function since we do not -- want to recover from async exceptions, see -- https://github.com/fpco/safe-exceptions#quickstart handleAsync :: () => (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a -- | Flipped catchJust. handleJust :: () => (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a -- | Same as upstream try, but will not catch asynchronous -- exceptions try :: () => (MonadCatch m, Exception e) => m a -> m (Either e a) -- | try specialized to only catching IOExceptions tryIO :: () => MonadCatch m => m a -> m (Either IOException a) -- | try specialized to catch all synchronous exceptions tryAny :: () => MonadCatch m => m a -> m (Either SomeException a) -- | Same as try, but fully force evaluation of the result value to -- find all impure exceptions. tryDeep :: () => (MonadCatch m, MonadIO m, Exception e, NFData a) => m a -> m (Either e a) -- | tryDeep specialized to catch all synchronous exceptions tryAnyDeep :: () => (MonadCatch m, MonadIO m, NFData a) => m a -> m (Either SomeException a) -- | try without async exception safety -- -- Generally it's better to avoid using this function since we do not -- want to recover from async exceptions, see -- https://github.com/fpco/safe-exceptions#quickstart tryAsync :: () => (MonadCatch m, Exception e) => m a -> m (Either e a) -- | A variant of try that takes an exception predicate to select -- which exceptions are caught. tryJust :: () => (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a) -- | Generalized version of Handler data Handler (m :: Type -> Type) a Handler :: (e -> m a) -> Handler (m :: Type -> Type) a -- | Same as upstream catches, but will not catch asynchronous -- exceptions catches :: () => (MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a -- | Same as catches, but fully force evaluation of the result value -- to find all impure exceptions. catchesDeep :: () => (MonadCatch m, MonadThrow m, MonadIO m, NFData a) => m a -> [Handler m a] -> m a -- | catches without async exception safety -- -- Generally it's better to avoid using this function since we do not -- want to recover from async exceptions, see -- https://github.com/fpco/safe-exceptions#quickstart catchesAsync :: () => (MonadCatch m, MonadThrow m) => m a -> [Handler m a] -> m a -- | Async safe version of onException onException :: () => MonadMask m => m a -> m b -> m a -- | Async safe version of bracket bracket :: forall m a b c. () => MonadMask m => m a -> (a -> m b) -> (a -> m c) -> m c -- | Async safe version of bracket_ bracket_ :: () => MonadMask m => m a -> m b -> m c -> m c -- | Async safe version of finally finally :: () => MonadMask m => m a -> m b -> m a -- | Like onException, but provides the handler the thrown -- exception. withException :: () => (MonadMask m, Exception e) => m a -> (e -> m b) -> m a -- | Async safe version of bracketOnError bracketOnError :: forall m a b c. () => MonadMask m => m a -> (a -> m b) -> (a -> m c) -> m c -- | A variant of bracketOnError where the return value from the -- first computation is not required. bracketOnError_ :: () => MonadMask m => m a -> m b -> m c -> m c -- | Async safe version of bracket with access to the exception in -- the cleanup action. bracketWithError :: forall m a b c. () => MonadMask m => m a -> (Maybe SomeException -> a -> m b) -> (a -> m c) -> m c -- | Wrap up an asynchronous exception to be treated as a synchronous -- exception -- -- This is intended to be created via toSyncException data SyncExceptionWrapper SyncExceptionWrapper :: e -> SyncExceptionWrapper -- | Convert an exception into a synchronous exception -- -- For synchronous exceptions, this is the same as toException. -- For asynchronous exceptions, this will wrap up the exception with -- SyncExceptionWrapper toSyncException :: Exception e => e -> SomeException -- | Wrap up a synchronous exception to be treated as an asynchronous -- exception -- -- This is intended to be created via toAsyncException data AsyncExceptionWrapper AsyncExceptionWrapper :: e -> AsyncExceptionWrapper -- | Convert an exception into an asynchronous exception -- -- For asynchronous exceptions, this is the same as toException. -- For synchronous exceptions, this will wrap up the exception with -- AsyncExceptionWrapper toAsyncException :: Exception e => e -> SomeException -- | Check if the given exception is synchronous isSyncException :: Exception e => e -> Bool -- | Check if the given exception is asynchronous isAsyncException :: Exception e => e -> Bool -- | A class for monads in which exceptions may be thrown. -- -- Instances should obey the following law: -- --
--   throwM e >> x = throwM e
--   
-- -- In other words, throwing an exception short-circuits the rest of the -- monadic computation. class Monad m => MonadThrow (m :: Type -> Type) -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
--   catch (throwM e) f = f e
--   
-- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: Type -> Type) -- | A class for monads which provide for the ability to account for all -- possible exit points from a computation, and to mask asynchronous -- exceptions. Continuation-based monads are invalid instances of this -- class. -- -- Instances should ensure that, in the following code: -- --
--   fg = f `finally` g
--   
-- -- The action g is called regardless of what occurs within -- f, including async exceptions. Some monads allow f -- to abort the computation via other effects than throwing an exception. -- For simplicity, we will consider aborting and throwing an exception to -- be two forms of "throwing an error". -- -- If f and g both throw an error, the error thrown by -- fg depends on which errors we're talking about. In a monad -- transformer stack, the deeper layers override the effects of the inner -- layers; for example, ExceptT e1 (Except e2) a represents a -- value of type Either e2 (Either e1 a), so throwing both an -- e1 and an e2 will result in Left e2. If -- f and g both throw an error from the same layer, -- instances should ensure that the error from g wins. -- -- Effects other than throwing an error are also overriden by the deeper -- layers. For example, StateT s Maybe a represents a value of -- type s -> Maybe (a, s), so if an error thrown from -- f causes this function to return Nothing, any -- changes to the state which f also performed will be erased. -- As a result, g will see the state as it was before -- f. Once g completes, f's error will be -- rethrown, so g' state changes will be erased as well. This is -- the normal interaction between effects in a monad transformer stack. -- -- By contrast, lifted-base's version of finally always -- discards all of g's non-IO effects, and g never sees -- any of f's non-IO effects, regardless of the layer ordering -- and regardless of whether f throws an error. This is not the -- result of interacting effects, but a consequence of -- MonadBaseControl's approach. class MonadCatch m => MonadMask (m :: Type -> Type) -- | Runs an action with asynchronous exceptions disabled. The action is -- provided a method for restoring the async. environment to what it was -- at the mask call. See Control.Exception's mask. mask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | Like mask, but the masked computation is not interruptible (see -- Control.Exception's uninterruptibleMask. WARNING: Only -- use if you need to mask exceptions around an interruptible operation -- AND you can guarantee the interruptible operation will only block for -- a short period of time. Otherwise you render the program/thread -- unresponsive and/or unkillable. uninterruptibleMask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | A generalized version of bracket which uses ExitCase to -- distinguish the different exit cases, and returns the values of both -- the use and release actions. In practice, this extra -- information is rarely needed, so it is often more convenient to use -- one of the simpler functions which are defined in terms of this one, -- such as bracket, finally, onError, and -- bracketOnError. -- -- This function exists because in order to thread their effects through -- the execution of bracket, monad transformers need values to be -- threaded from use to release and from -- release to the output value. -- -- NOTE This method was added in version 0.9.0 of this library. -- Previously, implementation of functions like bracket and -- finally in this module were based on the mask and -- uninterruptibleMask functions only, disallowing some classes of -- tranformers from having MonadMask instances (notably -- multi-exit-point transformers like ExceptT). If you are a -- library author, you'll now need to provide an implementation for this -- method. The StateT implementation demonstrates most of the -- subtleties: -- --
--   generalBracket acquire release use = StateT $ s0 -> do
--     ((b, _s2), (c, s3)) <- generalBracket
--       (runStateT acquire s0)
--       ((resource, s1) exitCase -> case exitCase of
--         ExitCaseSuccess (b, s2) -> runStateT (release resource (ExitCaseSuccess b)) s2
--   
--         -- In the two other cases, the base monad overrides use's state
--         -- changes and the state reverts to s1.
--         ExitCaseException e     -> runStateT (release resource (ExitCaseException e)) s1
--         ExitCaseAbort           -> runStateT (release resource ExitCaseAbort) s1
--       )
--       ((resource, s1) -> runStateT (use resource) s1)
--     return ((b, c), s3)
--   
-- -- The StateT s m implementation of generalBracket -- delegates to the m implementation of generalBracket. -- The acquire, use, and release arguments -- given to StateT's implementation produce actions of type -- StateT s m a, StateT s m b, and StateT s m -- c. In order to run those actions in the base monad, we need to -- call runStateT, from which we obtain actions of type m -- (a, s), m (b, s), and m (c, s). Since each -- action produces the next state, it is important to feed the state -- produced by the previous action to the next action. -- -- In the ExitCaseSuccess case, the state starts at s0, -- flows through acquire to become s1, flows through -- use to become s2, and finally flows through -- release to become s3. In the other two cases, -- release does not receive the value s2, so its action -- cannot see the state changes performed by use. This is fine, -- because in those two cases, an error was thrown in the base monad, so -- as per the usual interaction between effects in a monad transformer -- stack, those state changes get reverted. So we start from s1 -- instead. -- -- Finally, the m implementation of generalBracket -- returns the pairs (b, s) and (c, s). For monad -- transformers other than StateT, this will be some other type -- representing the effects and values performed and returned by the -- use and release actions. The effect part of the -- use result, in this case _s2, usually needs to be -- discarded, since those effects have already been incorporated in the -- release action. -- -- The only effect which is intentionally not incorporated in the -- release action is the effect of throwing an error. In that -- case, the error must be re-thrown. One subtlety which is easy to miss -- is that in the case in which use and release both -- throw an error, the error from release should take priority. -- Here is an implementation for ExceptT which demonstrates how -- to do this. -- --
--   generalBracket acquire release use = ExceptT $ do
--     (eb, ec) <- generalBracket
--       (runExceptT acquire)
--       (eresource exitCase -> case eresource of
--         Left e -> return (Left e) -- nothing to release, acquire didn't succeed
--         Right resource -> case exitCase of
--           ExitCaseSuccess (Right b) -> runExceptT (release resource (ExitCaseSuccess b))
--           ExitCaseException e       -> runExceptT (release resource (ExitCaseException e))
--           _                         -> runExceptT (release resource ExitCaseAbort))
--       (either (return . Left) (runExceptT . use))
--     return $ do
--       -- The order in which we perform those two Either effects determines
--       -- which error will win if they are both Lefts. We want the error from
--       -- release to win.
--       c <- ec
--       b <- eb
--       return (b, c)
--   
generalBracket :: MonadMask m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) -- | Like mask, but does not pass a restore action to the -- argument. mask_ :: MonadMask m => m a -> m a -- | Like uninterruptibleMask, but does not pass a restore -- action to the argument. uninterruptibleMask_ :: MonadMask m => m a -> m a -- | Catch all IOError (eqv. IOException) exceptions. Still -- somewhat too general, but better than using catchAll. See -- catchIf for an easy way of catching specific IOErrors -- based on the predicates in System.IO.Error. catchIOError :: MonadCatch m => m a -> (IOError -> m a) -> m a -- | Flipped catchIOError handleIOError :: MonadCatch m => (IOError -> m a) -> m a -> m a -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   
-- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
--   *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   
-- -- In more complicated examples, you may wish to define a whole hierarchy -- of exceptions: -- --
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e => SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e => e -> SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e => SomeException -> Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e => SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e => e -> SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e => SomeException -> Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   
-- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   
class (Typeable e, Show e) => Exception e toException :: Exception e => e -> SomeException fromException :: Exception e => SomeException -> Maybe e -- | Render this exception value in a human-friendly manner. -- -- Default implementation: show. displayException :: Exception e => e -> String -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable (a :: k) -- | The SomeException type is the root of the exception type -- hierarchy. When an exception of type e is thrown, behind the -- scenes it is encapsulated in a SomeException. data SomeException SomeException :: e -> SomeException -- | Superclass for asynchronous exceptions. data SomeAsyncException SomeAsyncException :: e -> SomeAsyncException -- | Exceptions that occur in the IO monad. An -- IOException records a more specific error type, a descriptive -- string and maybe the handle that was used when the error was flagged. data IOException -- | If the first argument evaluates to True, then the result is the -- second argument. Otherwise an AssertionFailed exception is -- raised, containing a String with the source file and line -- number of the call to assert. -- -- Assertions can normally be turned on or off with a compiler flag (for -- GHC, assertions are normally on unless optimisation is turned on with -- -O or the -fignore-asserts option is given). When -- assertions are turned off, the first argument to assert is -- ignored, and the second argument is returned as the result. assert :: Bool -> a -> a instance GHC.Show.Show Control.Exception.Safe.AsyncExceptionWrapper instance GHC.Exception.Type.Exception Control.Exception.Safe.AsyncExceptionWrapper instance GHC.Show.Show Control.Exception.Safe.SyncExceptionWrapper instance GHC.Exception.Type.Exception Control.Exception.Safe.SyncExceptionWrapper instance GHC.Show.Show Control.Exception.Safe.StringException instance GHC.Exception.Type.Exception Control.Exception.Safe.StringException