我正在使用Haskell编写一个应用程序,如果
然而,我不知道应该捕获哪些错误以及如何从中提取信息。例如,假设“/bin”是一个目录,“/bin/ls”是一个文件,
与前面的例子相关,似乎没有一种便携式的方法来捕获“不适当的类型”错误。查看GHC.IO.Exception,
总之,我的问题如下:
1. 我应该捕获哪些异常以处理
更新:
根据@ErikR的回答,我正在查看
readFile
或writeFile
失败,我希望向用户显示有意义的错误消息。我目前使用Control.Exception.tryJust
捕获IOError
并将其转换为人类可读的文本。然而,我不知道应该捕获哪些错误以及如何从中提取信息。例如,假设“/bin”是一个目录,“/bin/ls”是一个文件,
readFile "/bin"
和readFile "/bin/ls/asdf"
都会给出“不适当的类型”,但我认为它们是不同的错误。在第一种情况下,我可以通过处理目录中的每个文件来恢复,而第二种情况更像是一种“不存在”的错误类型。与前面的例子相关,似乎没有一种便携式的方法来捕获“不适当的类型”错误。查看GHC.IO.Exception,
InappropriateType
被标记为仅限于 GHC ,因此我不能在ioeGetErrorType
上进行模式匹配。我可以在ioeGetErrorString
上进行模式匹配,但我不确定这些字符串是否在不同的平台、编译器和区域设置中总是相同。总之,我的问题如下:
1. 我应该捕获哪些异常以处理
readFile
/writeFile
?
2. 一旦我有了一个异常,我应该如何提取其中的信息?
3. 是否存在一种便携式的方法来捕获仅适用于GHC的异常,例如InappropriateType
?更新:
根据@ErikR的回答,我正在查看
GHC.IO.Exception.IOException
的字段,使用以下Haskell程序:import Control.Exception (try)
import GHC.IO.Exception (IOException(..))
import qualified Data.ByteString as B
main :: IO ()
main = do
try (readFile "/nonexistent") >>= printException
try (writeFile "/dev/full" " ") >>= printException
try (readFile "/root") >>= printException
try (readFile "/bin") >>= printException
try (writeFile "/bin" "") >>= printException
try (readFile "/bin/ls/asdf") >>= printException
try (writeFile "/bin/ls/asdf" "") >>= printException
try (B.readFile "/dev/null") >>= printException
-- I have /media/backups mounted as read-only. Substitute your own read-only
-- filesystem for this one
try (writeFile "/media/backups/asdf" "") >>= printException
printException :: Either IOError a -> IO ()
printException (Right _) = putStrLn "No exception caught"
printException (Left e) = putStrLn $ concat [ "ioe_filename = "
, show $ ioe_filename e
, ", ioe_description = "
, show $ ioe_description e
, ", ioe_errno = "
, show $ ioe_errno e
]
在Debian Sid GNU/Linux上,使用GHC 7.10.3的输出结果如下:
ioe_filename = Just "/nonexistent", ioe_description = "No such file or directory", ioe_errno = Just 2
ioe_filename = Just "/dev/full", ioe_description = "No space left on device", ioe_errno = Just 28
ioe_filename = Just "/root", ioe_description = "Permission denied", ioe_errno = Just 13
ioe_filename = Just "/bin", ioe_description = "is a directory", ioe_errno = Nothing
ioe_filename = Just "/bin", ioe_description = "Is a directory", ioe_errno = Just 21
ioe_filename = Just "/bin/ls/asdf", ioe_description = "Not a directory", ioe_errno = Just 20
ioe_filename = Just "/bin/ls/asdf", ioe_description = "Not a directory", ioe_errno = Just 20
ioe_filename = Just "/dev/null", ioe_description = "not a regular file", ioe_errno = Nothing
ioe_filename = Just "/media/backups/asdf", ioe_description = "Read-only file system", ioe_errno = Just 30