catchConvertIO :: (String -> a) -> IO b -> IO (Either a b)
catchConvertIO excep action = do
  err <- tryIOError action
  return $ case err of
    Left e -> Left . excep $ show e
    Right r -> Right r

-- | Catch all IOErrors that might occur and convert them to a custom error type
-- with the IOError message postpended to the given string
catchConvertIO :: (String -> a) -> IO b -> IO (Either a b)
catchConvertIO excep action = do
  err <- tryIOError action
  return $ case err of
    Left e -> Left . excep $ show e
    Right r -> Right r

-- | Catch all IOErrors that might occur and convert them to a custom error type
-- with the IOError message postpended to the given string
catchConvertIO excep action = do
  err <- tryIOError action
  return $ case err of
    Left e -> Left . excep $ show e
    Right r -> Right r

-- | Catch all IOErrors that might occur and convert them to a custom error type
-- with the IOError message postpended to the given string