Switch to new-style exception handling
authorIustin Pop <iustin@google.com>
Sun, 25 Mar 2012 14:26:02 +0000 (16:26 +0200)
committerIustin Pop <iustin@google.com>
Mon, 26 Mar 2012 08:54:08 +0000 (10:54 +0200)
Currently, we're using Prelude.catch to handle I/O errors in
htools. This style of error handling has been deprecated for a while,
but it still used to work without warnings.

However, the GHC release 7.4 has started to emit deprecation warnings
for it, so we change to the Control.Exception module; the code is a
bit less clean since we only care about I/O errors (but
Control.Exception deals with other error types too), so we have to
filter the exceptions.

Note that the new style exception handling is not really "new"; it has
existed since at least GHC 6.12, which is our oldest supported
compiler.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: RenĂ© Nussbaumer <rn@google.com>

htools/Ganeti/HTools/ExtLoader.hs
htools/Ganeti/HTools/Rapi.hs
htools/htools.hs

index 2defade..bd258f5 100644 (file)
@@ -34,7 +34,9 @@ module Ganeti.HTools.ExtLoader
   ) where
 
 import Control.Monad
+import Control.Exception
 import Data.Maybe (isJust, fromJust)
+import Prelude hiding (catch)
 import System.FilePath
 import System.IO
 import Text.Printf (hPrintf)
@@ -53,7 +55,7 @@ import Ganeti.HTools.Utils (sepSplit, tryRead, exitIfBad, exitWhen)
 
 -- | Error beautifier.
 wrapIO :: IO (Result a) -> IO (Result a)
-wrapIO = flip catch (return . Bad . show)
+wrapIO = flip catch (\e -> return . Bad . show $ (e::IOException))
 
 -- | Parses a user-supplied utilisation string.
 parseUtilisation :: String -> Result (String, DynUtil)
index d52abab..710bfbb 100644 (file)
@@ -30,6 +30,7 @@ module Ganeti.HTools.Rapi
   , parseData
   ) where
 
+import Control.Exception
 import Data.List (isPrefixOf)
 import Data.Maybe (fromMaybe)
 #ifndef NO_CURL
@@ -37,6 +38,7 @@ import Network.Curl
 import Network.Curl.Types ()
 #endif
 import Control.Monad
+import Prelude hiding (catch)
 import Text.JSON (JSObject, fromJSObject, decodeStrict)
 import Text.JSON.Types (JSValue(..))
 import Text.Printf (printf)
@@ -83,7 +85,8 @@ getUrl url = do
 -- | Helper to convert I/O errors in 'Bad' values.
 ioErrToResult :: IO a -> IO (Result a)
 ioErrToResult ioaction =
-  catch (ioaction >>= return . Ok) (return . Bad . show)
+  catch (ioaction >>= return . Ok)
+        (\e -> return . Bad . show $ (e::IOException))
 
 -- | Append the default port if not passed in.
 formatHost :: String -> String
index f35c18c..2e847d7 100644 (file)
@@ -25,10 +25,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 module Main (main) where
 
+import Control.Exception
+import Control.Monad (guard)
 import Data.Char (toLower)
+import Prelude hiding (catch)
 import System.Environment
 import System.Exit
 import System.IO
+import System.IO.Error (isDoesNotExistError)
 
 import Ganeti.HTools.Utils
 import Ganeti.HTools.CLI (parseOpts)
@@ -47,7 +51,8 @@ usage name = do
 
 main :: IO ()
 main = do
-  binary <- getEnv "HTOOLS" `catch` const getProgName
+  binary <- catchJust (guard . isDoesNotExistError)
+            (getEnv "HTOOLS") (const getProgName)
   let name = map toLower binary
       boolnames = map (\(x, y) -> (x == name, Just y)) personalities
   case select Nothing boolnames of