summaryrefslogtreecommitdiff
path: root/Utility/Exception.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@debian.org>2014-04-11 01:19:05 -0400
committerJoey Hess <joeyh@debian.org>2014-04-11 01:19:05 -0400
commitbe02ef96aa89a6af554a622f266d700ac0c98fdf (patch)
tree63c784022afb05b73fedf0df3fd269de0d31baf8 /Utility/Exception.hs
propellor (0.3.0) unstable; urgency=medium
* ipv6to4: Ensure interface is brought up automatically on boot. * Enabling unattended upgrades now ensures that cron is installed and running to perform them. * Properties can be scheduled to only be checked after a given time period. * Fix bootstrapping of dependencies. * Fix compilation on Debian stable. * Include security updates in sources.list for stable and testing. * Use ssh connection caching, especially when bootstrapping. * Properties now run in a Propellor monad, which provides access to attributes of the host. # imported from the archive
Diffstat (limited to 'Utility/Exception.hs')
-rw-r--r--Utility/Exception.hs59
1 files changed, 59 insertions, 0 deletions
diff --git a/Utility/Exception.hs b/Utility/Exception.hs
new file mode 100644
index 00000000..cf2c615c
--- /dev/null
+++ b/Utility/Exception.hs
@@ -0,0 +1,59 @@
+{- Simple IO exception handling (and some more)
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Utility.Exception where
+
+import Control.Exception
+import qualified Control.Exception as E
+import Control.Applicative
+import Control.Monad
+import System.IO.Error (isDoesNotExistError)
+import Utility.Data
+
+{- Catches IO errors and returns a Bool -}
+catchBoolIO :: IO Bool -> IO Bool
+catchBoolIO a = catchDefaultIO False a
+
+{- Catches IO errors and returns a Maybe -}
+catchMaybeIO :: IO a -> IO (Maybe a)
+catchMaybeIO a = catchDefaultIO Nothing $ Just <$> a
+
+{- Catches IO errors and returns a default value. -}
+catchDefaultIO :: a -> IO a -> IO a
+catchDefaultIO def a = catchIO a (const $ return def)
+
+{- Catches IO errors and returns the error message. -}
+catchMsgIO :: IO a -> IO (Either String a)
+catchMsgIO a = either (Left . show) Right <$> tryIO a
+
+{- catch specialized for IO errors only -}
+catchIO :: IO a -> (IOException -> IO a) -> IO a
+catchIO = E.catch
+
+{- try specialized for IO errors only -}
+tryIO :: IO a -> IO (Either IOException a)
+tryIO = try
+
+{- Catches all exceptions except for async exceptions.
+ - This is often better to use than catching them all, so that
+ - ThreadKilled and UserInterrupt get through.
+ -}
+catchNonAsync :: IO a -> (SomeException -> IO a) -> IO a
+catchNonAsync a onerr = a `catches`
+ [ Handler (\ (e :: AsyncException) -> throw e)
+ , Handler (\ (e :: SomeException) -> onerr e)
+ ]
+
+tryNonAsync :: IO a -> IO (Either SomeException a)
+tryNonAsync a = (Right <$> a) `catchNonAsync` (return . Left)
+
+{- Catches only DoesNotExist exceptions, and lets all others through. -}
+tryWhenExists :: IO a -> IO (Maybe a)
+tryWhenExists a = eitherToMaybe <$>
+ tryJust (guard . isDoesNotExistError) a