如何从IO捕获异常并打印其错误。

时间:2018-11-19 16:00:17

标签: haskell

我想从IO捕获异常,并检查typeOf引发了哪种异常,然后使用特定的异常进行模式匹配,以便专门处理该异常。但是以下代码无法正常工作。

import Control.Exception (SomeException, handle)
import Data.Typeable (typeOf)
import System.Environment (getEnv)

main :: IO ()
main = handle missingEnv exe
  where
    exe = do
      env <- getEnv "MISSING_ENV"
      print env
      file <- readFile "/file-does-not-exist"
      print file

missingEnv :: SomeException -> IO ()
missingEnv e = do
  print e
  print $ typeOf e
  return ()

上面的代码将显示以下错误,但仅显示“ SomeException”,该名称没有Exception类型的特定名称。

MISSING_ENV: getEnv: does not exist (no environment variable)
SomeException

您可能建议我使用lookupEnv,但这不是我的意思,因为我想学习如何捕获异常,而不是避免异常。

是否可以检查IO中引发的异常的特定“类型”?

是否还可以检查MonadError中引发的异常的特定“类型”?

2 个答案:

答案 0 :(得分:2)

是的,您可以检查异常的类型:

logSomeException :: SomeException -> IO ()
logSomeException (SomeException e) = print (typeOf e)

答案 1 :(得分:2)

您已经使用SomeException颠覆了整个异常类型匹配机制。如果您要处理特定种类的异常,请执行此操作,不要一路转换成SomeException或从中转换出来。例如:

import Control.Exception (IOException, handle, throwIO)
import System.Environment (getEnv)
import System.IO.Error (isDoesNotExistError)

main :: IO ()
main = handle missingEnv exe
  where
    exe = do
      env <- getEnv "MISSING_ENV"
      print env
      file <- readFile "/file-does-not-exist"
      print file

missingEnv :: IOException -> IO ()
missingEnv e | isDoesNotExistError = print e
             | otherwise = throwIO e