module Matterhorn.IOUtil
  ( convertIOException
  )
where

import Prelude ()
import Matterhorn.Prelude

import Control.Exception
import Control.Monad.Trans.Except
import System.IO.Error ( ioeGetErrorString )


convertIOException :: IO a -> ExceptT String IO a
convertIOException :: IO a -> ExceptT String IO a
convertIOException IO a
act = do
    Either String a
result <- IO (Either String a) -> ExceptT String IO (Either String a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either String a) -> ExceptT String IO (Either String a))
-> IO (Either String a) -> ExceptT String IO (Either String a)
forall a b. (a -> b) -> a -> b
$ (a -> Either String a
forall a b. b -> Either a b
Right (a -> Either String a) -> IO a -> IO (Either String a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO a
act) IO (Either String a)
-> (IOError -> IO (Either String a)) -> IO (Either String a)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch`
                       (\(IOError
e::IOError) -> Either String a -> IO (Either String a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String a -> IO (Either String a))
-> Either String a -> IO (Either String a)
forall a b. (a -> b) -> a -> b
$ String -> Either String a
forall a b. a -> Either a b
Left (String -> Either String a) -> String -> Either String a
forall a b. (a -> b) -> a -> b
$ IOError -> String
ioeGetErrorString IOError
e)
    case Either String a
result of
        Left String
e -> String -> ExceptT String IO a
forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
throwE String
e
        Right a
v -> a -> ExceptT String IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
v