{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
#ifdef TRUSTWORTHY
{-# LANGUAGE Trustworthy #-}
#endif
#ifndef MIN_VERSION_base
#define MIN_VERSION_base(x,y,z) 1
#endif
#ifndef MIN_VERSION_exceptions
#define MIN_VERSION_exceptions 1
#endif
#if !(MIN_VERSION_exceptions(0,4,0))
#define MonadThrow MonadCatch
#endif
module Control.Exception.Lens
(
catching, catching_
, handling, handling_
, trying, trying_
, throwing
, throwingM
, throwingTo
, mappedException, mappedException'
, exception
, Handleable(..)
, AsIOException(..)
, AsArithException(..)
, _Overflow
, _Underflow
, _LossOfPrecision
, _DivideByZero
, _Denormal
#if MIN_VERSION_base(4,6,0)
, _RatioZeroDenominator
#endif
, AsArrayException(..)
, _IndexOutOfBounds
, _UndefinedElement
, AsAssertionFailed(..)
, AsAsyncException(..)
, _StackOverflow
, _HeapOverflow
, _ThreadKilled
, _UserInterrupt
, AsNonTermination(..)
, AsNestedAtomically(..)
, AsBlockedIndefinitelyOnMVar(..)
, AsBlockedIndefinitelyOnSTM(..)
, AsDeadlock(..)
, AsNoMethodError(..)
, AsPatternMatchFail(..)
, AsRecConError(..)
, AsRecSelError(..)
, AsRecUpdError(..)
, AsErrorCall(..)
, AsHandlingException(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Catch as Catch
import Control.Exception as Exception hiding (try, tryJust, catchJust)
import Control.Lens
import Control.Lens.Internal.Exception
import Data.Monoid
import GHC.Conc (ThreadId)
import Prelude
( const, either, flip, id
, (.)
, Maybe(..), Either(..), String
)
#ifdef HLINT
{-# ANN module "HLint: ignore Use Control.Exception.catch" #-}
#endif
exception :: Exception a => Prism' SomeException a
exception = prism' toException fromException
{-# INLINE exception #-}
catching :: MonadCatch m => Getting (First a) SomeException a -> m r -> (a -> m r) -> m r
catching l = catchJust (preview l)
{-# INLINE catching #-}
catching_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m r -> m r
catching_ l a b = catchJust (preview l) a (const b)
{-# INLINE catching_ #-}
handling :: MonadCatch m => Getting (First a) SomeException a -> (a -> m r) -> m r -> m r
handling l = flip (catching l)
{-# INLINE handling #-}
handling_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m r -> m r
handling_ l = flip (catching_ l)
{-# INLINE handling_ #-}
trying :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Either a r)
trying l = tryJust (preview l)
{-# INLINE trying #-}
trying_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Maybe r)
trying_ l m = preview _Right `liftM` trying l m
{-# INLINE trying_ #-}
throwing :: AReview s SomeException a b -> b -> r
throwing l = reviews l Exception.throw
{-# INLINE throwing #-}
throwingM :: MonadThrow m => AReview s SomeException a b -> b -> m r
throwingM l = reviews l throwM
{-# INLINE throwingM #-}
throwingTo :: MonadIO m => ThreadId -> AReview s SomeException a b -> b -> m ()
throwingTo tid l = reviews l (liftIO . throwTo tid)
{-# INLINE throwingTo #-}
mappedException :: (Exception e, Exception e') => Setter s s e e'
mappedException = sets mapException
{-# INLINE mappedException #-}
mappedException' :: Exception e' => Setter s s SomeException e'
mappedException' = mappedException
{-# INLINE mappedException' #-}
class AsIOException t where
_IOException :: Prism' t IOException
instance AsIOException IOException where
_IOException = id
{-# INLINE _IOException #-}
instance AsIOException SomeException where
_IOException = exception
{-# INLINE _IOException #-}
class AsArithException t where
_ArithException :: Prism' t ArithException
instance AsArithException ArithException where
_ArithException = id
{-# INLINE _ArithException #-}
instance AsArithException SomeException where
_ArithException = exception
{-# INLINE _ArithException #-}
_Overflow :: AsArithException t => Prism' t ()
_Overflow = _ArithException . dimap seta (either id id) . right' . rmap (Overflow <$) where
seta Overflow = Right ()
seta t = Left (pure t)
{-# INLINE _Overflow #-}
_Underflow :: AsArithException t => Prism' t ()
_Underflow = _ArithException . dimap seta (either id id) . right' . rmap (Underflow <$) where
seta Underflow = Right ()
seta t = Left (pure t)
{-# INLINE _Underflow #-}
_LossOfPrecision :: AsArithException t => Prism' t ()
_LossOfPrecision = _ArithException . dimap seta (either id id) . right' . rmap (LossOfPrecision <$) where
seta LossOfPrecision = Right ()
seta t = Left (pure t)
{-# INLINE _LossOfPrecision #-}
_DivideByZero :: AsArithException t => Prism' t ()
_DivideByZero = _ArithException . dimap seta (either id id) . right' . rmap (DivideByZero <$) where
seta DivideByZero = Right ()
seta t = Left (pure t)
{-# INLINE _DivideByZero #-}
_Denormal :: AsArithException t => Prism' t ()
_Denormal = _ArithException . dimap seta (either id id) . right' . rmap (Denormal <$) where
seta Denormal = Right ()
seta t = Left (pure t)
{-# INLINE _Denormal #-}
#if MIN_VERSION_base(4,6,0)
_RatioZeroDenominator :: AsArithException t => Prism' t ()
_RatioZeroDenominator = _ArithException . dimap seta (either id id) . right' . rmap (RatioZeroDenominator <$) where
seta RatioZeroDenominator = Right ()
seta t = Left (pure t)
{-# INLINE _RatioZeroDenominator #-}
#endif
class AsArrayException t where
_ArrayException :: Prism' t ArrayException
instance AsArrayException ArrayException where
_ArrayException = id
{-# INLINE _ArrayException #-}
instance AsArrayException SomeException where
_ArrayException = exception
{-# INLINE _ArrayException #-}
_IndexOutOfBounds :: AsArrayException t => Prism' t String
_IndexOutOfBounds = _ArrayException . dimap seta (either id id) . right' . rmap (fmap IndexOutOfBounds) where
seta (IndexOutOfBounds r) = Right r
seta t = Left (pure t)
{-# INLINE _IndexOutOfBounds #-}
_UndefinedElement :: AsArrayException t => Prism' t String
_UndefinedElement = _ArrayException . dimap seta (either id id) . right' . rmap (fmap UndefinedElement) where
seta (UndefinedElement r) = Right r
seta t = Left (pure t)
{-# INLINE _UndefinedElement #-}
class AsAssertionFailed t where
_AssertionFailed :: Prism' t String
instance AsAssertionFailed AssertionFailed where
_AssertionFailed = _Wrapping AssertionFailed
{-# INLINE _AssertionFailed #-}
instance AsAssertionFailed SomeException where
_AssertionFailed = exception._Wrapping AssertionFailed
{-# INLINE _AssertionFailed #-}
class AsAsyncException t where
_AsyncException :: Prism' t AsyncException
instance AsAsyncException AsyncException where
_AsyncException = id
{-# INLINE _AsyncException #-}
instance AsAsyncException SomeException where
_AsyncException = exception
{-# INLINE _AsyncException #-}
_StackOverflow :: AsAsyncException t => Prism' t ()
_StackOverflow = _AsyncException . dimap seta (either id id) . right' . rmap (StackOverflow <$) where
seta StackOverflow = Right ()
seta t = Left (pure t)
{-# INLINE _StackOverflow #-}
_HeapOverflow :: AsAsyncException t => Prism' t ()
_HeapOverflow = _AsyncException . dimap seta (either id id) . right' . rmap (HeapOverflow <$) where
seta HeapOverflow = Right ()
seta t = Left (pure t)
{-# INLINE _HeapOverflow #-}
_ThreadKilled :: AsAsyncException t => Prism' t ()
_ThreadKilled = _AsyncException . dimap seta (either id id) . right' . rmap (ThreadKilled <$) where
seta ThreadKilled = Right ()
seta t = Left (pure t)
{-# INLINE _ThreadKilled #-}
_UserInterrupt :: AsAsyncException t => Prism' t ()
_UserInterrupt = _AsyncException . dimap seta (either id id) . right' . rmap (UserInterrupt <$) where
seta UserInterrupt = Right ()
seta t = Left (pure t)
{-# INLINE _UserInterrupt #-}
class AsNonTermination t where
_NonTermination :: Prism' t ()
instance AsNonTermination NonTermination where
_NonTermination = trivial NonTermination
{-# INLINE _NonTermination #-}
instance AsNonTermination SomeException where
_NonTermination = exception.trivial NonTermination
{-# INLINE _NonTermination #-}
class AsNestedAtomically t where
_NestedAtomically :: Prism' t ()
instance AsNestedAtomically NestedAtomically where
_NestedAtomically = trivial NestedAtomically
{-# INLINE _NestedAtomically #-}
instance AsNestedAtomically SomeException where
_NestedAtomically = exception.trivial NestedAtomically
{-# INLINE _NestedAtomically #-}
class AsBlockedIndefinitelyOnMVar t where
_BlockedIndefinitelyOnMVar :: Prism' t ()
instance AsBlockedIndefinitelyOnMVar BlockedIndefinitelyOnMVar where
_BlockedIndefinitelyOnMVar = trivial BlockedIndefinitelyOnMVar
{-# INLINE _BlockedIndefinitelyOnMVar #-}
instance AsBlockedIndefinitelyOnMVar SomeException where
_BlockedIndefinitelyOnMVar = exception.trivial BlockedIndefinitelyOnMVar
{-# INLINE _BlockedIndefinitelyOnMVar #-}
class AsBlockedIndefinitelyOnSTM t where
_BlockedIndefinitelyOnSTM :: Prism' t ()
instance AsBlockedIndefinitelyOnSTM BlockedIndefinitelyOnSTM where
_BlockedIndefinitelyOnSTM = trivial BlockedIndefinitelyOnSTM
{-# INLINE _BlockedIndefinitelyOnSTM #-}
instance AsBlockedIndefinitelyOnSTM SomeException where
_BlockedIndefinitelyOnSTM = exception.trivial BlockedIndefinitelyOnSTM
{-# INLINE _BlockedIndefinitelyOnSTM #-}
class AsDeadlock t where
_Deadlock :: Prism' t ()
instance AsDeadlock Deadlock where
_Deadlock = trivial Deadlock
{-# INLINE _Deadlock #-}
instance AsDeadlock SomeException where
_Deadlock = exception.trivial Deadlock
{-# INLINE _Deadlock #-}
class AsNoMethodError t where
_NoMethodError :: Prism' t String
instance AsNoMethodError NoMethodError where
_NoMethodError = _Wrapping NoMethodError
{-# INLINE _NoMethodError #-}
instance AsNoMethodError SomeException where
_NoMethodError = exception._Wrapping NoMethodError
{-# INLINE _NoMethodError #-}
class AsPatternMatchFail t where
_PatternMatchFail :: Prism' t String
instance AsPatternMatchFail PatternMatchFail where
_PatternMatchFail = _Wrapping PatternMatchFail
{-# INLINE _PatternMatchFail #-}
instance AsPatternMatchFail SomeException where
_PatternMatchFail = exception._Wrapping PatternMatchFail
{-# INLINE _PatternMatchFail #-}
class AsRecConError t where
_RecConError :: Prism' t String
instance AsRecConError RecConError where
_RecConError = _Wrapping RecConError
{-# INLINE _RecConError #-}
instance AsRecConError SomeException where
_RecConError = exception._Wrapping RecConError
{-# INLINE _RecConError #-}
class AsRecSelError t where
_RecSelError :: Prism' t String
instance AsRecSelError RecSelError where
_RecSelError = _Wrapping RecSelError
{-# INLINE _RecSelError #-}
instance AsRecSelError SomeException where
_RecSelError = exception._Wrapping RecSelError
{-# INLINE _RecSelError #-}
class AsRecUpdError t where
_RecUpdError :: Prism' t String
instance AsRecUpdError RecUpdError where
_RecUpdError = _Wrapping RecUpdError
{-# INLINE _RecUpdError #-}
instance AsRecUpdError SomeException where
_RecUpdError = exception._Wrapping RecUpdError
{-# INLINE _RecUpdError #-}
class AsErrorCall t where
_ErrorCall :: Prism' t String
instance AsErrorCall ErrorCall where
_ErrorCall = _Wrapping ErrorCall
{-# INLINE _ErrorCall #-}
instance AsErrorCall SomeException where
_ErrorCall = exception._Wrapping ErrorCall
{-# INLINE _ErrorCall #-}
class AsHandlingException t where
_HandlingException :: Prism' t ()
instance AsHandlingException HandlingException where
_HandlingException = trivial HandlingException
{-# INLINE _HandlingException #-}
instance AsHandlingException SomeException where
_HandlingException = exception.trivial HandlingException
{-# INLINE _HandlingException #-}
trivial :: t -> Iso' t ()
trivial t = const () `iso` const t