处理 SomeException 异常被忽略。

3

我有一个常规的Haskell代码,用于读取文件并处理任何异常:

handle ((\_->return "ERROR") :: SomeException -> IO String) $ readFile "file.txt"

当我试图读取错误编码的文件时,总是会出现错误:

*** Exception: file.txt: hGetContents: invalid argument (invalid byte sequence)

程序没有进入我的异常处理函数中。我也尝试使用 IOErrorIOException 类型替换 SomeException,但并没有改变任何内容。

如果使用句柄打开类似的文件,并使用以下代码读取:

handle ((\_->return "ERROR") :: SomeException -> IO String) (hGetContents myHandle)

运行正常。

如何正确地捕获由readFile传递的hGetContents抛出的异常?


3
readFile 函数似乎有惰性 IO 的特点 - 只有在返回字符串后才读取文件?尝试在 handle 内强制求值。 - Bergi
@Bergi,我在ghci中运行了这段代码,所以结果立即被强制执行。 - Shadasviar
4
@Shadasviar的话并不意味着Bergi的诊断有误,实际上它支持了这个猜想。1. 运行readFile函数,获取一些字节(或者可能还没有)。2. 返回一个(惰性)的String,现在不再处于handle函数内。3. 尝试在REPL上打印整个字符串,从而强制读取所有内容。4. 遇到错误并抛出异常。 - Thomas M. DuBuisson
1个回答

5
您可以强制在catch的范围内读取整个字符串:
Control.Exception.handle
      ((\_ -> return "ERR") :: Control.Exception.SomeException -> IO String)
      (Prelude.readFile "file.txt" >>= \res -> res `deepseq` (pure res))
"ERR"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接