{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
module Control.Exception.Annotation.Utils
(
ExceptionProxy (..),
matchesException,
setIgnoreKnownCallStackHandler,
ignoreKnownCallStackHandler,
ignoreCallStackHandler,
)
where
import Control.Monad.Catch
( Exception (displayException, fromException, toException),
SomeException,
)
import Data.List qualified as L
import Data.Maybe qualified as Maybe
import GHC.Conc (getUncaughtExceptionHandler, setUncaughtExceptionHandler)
data ExceptionProxy = forall e. (Exception e) => MkExceptionProxy
setIgnoreKnownCallStackHandler :: [ExceptionProxy] -> IO ()
setIgnoreKnownCallStackHandler :: [ExceptionProxy] -> IO ()
setIgnoreKnownCallStackHandler [ExceptionProxy]
proxies =
IO (SomeException -> IO ())
getUncaughtExceptionHandler
IO (SomeException -> IO ())
-> ((SomeException -> IO ()) -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (SomeException -> IO ()) -> IO ()
setUncaughtExceptionHandler ((SomeException -> IO ()) -> IO ())
-> ((SomeException -> IO ()) -> SomeException -> IO ())
-> (SomeException -> IO ())
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ExceptionProxy]
-> (SomeException -> IO ()) -> SomeException -> IO ()
ignoreKnownCallStackHandler [ExceptionProxy]
proxies
ignoreKnownCallStackHandler ::
[ExceptionProxy] ->
(SomeException -> IO ()) ->
SomeException ->
IO ()
ignoreKnownCallStackHandler :: [ExceptionProxy]
-> (SomeException -> IO ()) -> SomeException -> IO ()
ignoreKnownCallStackHandler [ExceptionProxy]
proxies SomeException -> IO ()
prevHandler SomeException
ex =
if [ExceptionProxy] -> SomeException -> Bool
forall e. Exception e => [ExceptionProxy] -> e -> Bool
matchesException [ExceptionProxy]
proxies SomeException
ex
then SomeException -> IO ()
ignoreCallStackHandler SomeException
ex
else SomeException -> IO ()
prevHandler SomeException
ex
ignoreCallStackHandler :: SomeException -> IO ()
ignoreCallStackHandler :: SomeException -> IO ()
ignoreCallStackHandler = String -> IO ()
putStrLn (String -> IO ())
-> (SomeException -> String) -> SomeException -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall e. Exception e => e -> String
displayException
matchesException :: (Exception e) => [ExceptionProxy] -> e -> Bool
matchesException :: forall e. Exception e => [ExceptionProxy] -> e -> Bool
matchesException [ExceptionProxy]
proxies e
ex = (ExceptionProxy -> Bool) -> [ExceptionProxy] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
L.any ExceptionProxy -> Bool
isMatch [ExceptionProxy]
proxies
where
se :: SomeException
se = e -> SomeException
forall e. Exception e => e -> SomeException
toException e
ex
isMatch :: ExceptionProxy -> Bool
isMatch (MkExceptionProxy @ex) = Maybe e -> Bool
forall a. Maybe a -> Bool
Maybe.isJust (forall e. Exception e => SomeException -> Maybe e
fromException @ex SomeException
se)