module Control.Exception.Extra( module Control.Exception, retry, showException, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool ) where import Control.Exception import Control.Monad -- | Print an exception, but if that exception itself contains exceptions, simply print -- @\@. Since Haskell is a lazy language it is possible to throw -- exceptions that are themselves undefined. This function is useful to report them to users. showException :: SomeException -> IO String showException = f . show where f xs = do r <- try_ $ evaluate xs case r of Left e -> return "" Right [] -> return [] Right (x:xs) -> fmap (x :) $ f xs -- | Ignore any exceptions thrown by the action and continue as normal. ignore :: IO () -> IO () ignore = void . try_ retry :: Int -> IO a -> IO a retry i x | i <= 0 = error "retry count must be 1 or more" retry 1 x = x retry i x = do res <- try_ x case res of Left _ -> retry (i-1) x Right v -> return v catch_ :: IO a -> (SomeException -> IO a) -> IO a catch_ = Control.Exception.catch catchJust_ :: (SomeException -> Maybe b) -> IO a -> (b -> IO a) -> IO a catchJust_ = catchJust handle_ :: (SomeException -> IO a) -> IO a -> IO a handle_ = handle handleJust_ :: (SomeException -> Maybe b) -> (b -> IO a) -> IO a -> IO a handleJust_ = handleJust try_ :: IO a -> IO (Either SomeException a) try_ = try tryJust_ :: (SomeException -> Maybe b) -> IO a -> IO (Either b a) tryJust_ = tryJust catchBool :: Exception e => (e -> Bool) -> IO a -> (e -> IO a) -> IO a catchBool f a b = catchJust (bool f) a b handleBool :: Exception e => (e -> Bool) -> (e -> IO a) -> IO a -> IO a handleBool f a b = handleJust (bool f) a b tryBool :: Exception e => (e -> Bool) -> IO a -> IO (Either e a) tryBool f a = tryJust (bool f) a bool :: Exception e => (e -> Bool) -> (e -> Maybe e) bool f x = if f x then Just x else Nothing