6

我正在尝试下载包含在 html 文件中的所有 png 文件。不过,我无法捕获 404 状态异常,而是我的程序崩溃了。

这是一些示例来演示:

import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L

main = do
    let badUrl = "http://www.google.com/intl/en_com/images/srpr/WRONG.png"    
    imgData <- (simpleHttp badUrl) `catch` statusExceptionHandler  
    L.writeFile "my.png" imgData

statusExceptionHandler ::  t -> IO L.ByteString
statusExceptionHandler e = (putStrLn "oops") >> (return L.empty)

我的“哎呀”消息永远不会打印,而是应用程序崩溃:

StatusCodeException (Status {statusCode = 404, statusMessage = "Not Found"}) [("Content-Type","text/html; charset=UTF-8"),("X-Content-Type-Options","nosniff "),("Date","Fri, 27 Jan 2012 03:10:34 GMT"),("Server","sffe"),("Content-Length","964"),("X-XSS -保护","1;模式=块")]

我究竟做错了什么?

更新:

按照 Thoma 的建议,我将代码更改为以下代码段,现在可以进行适当的异常处理。

main = do
    let badUrl = "http://www.google.com/intl/en_com/images/srpr/WRONG.png"    
    imgData <- (simpleHttp badUrl) `X.catch` statusExceptionHandler  
    case imgData of x | x == L.empty -> return () 
                      | otherwise    -> L.writeFile "my.png" imgData

statusExceptionHandler ::  HttpException -> IO L.ByteString
statusExceptionHandler (StatusCodeException status headers) = 
    putStr "An error occured during download: "
    >> (putStrLn $ show status)
    >> (return L.empty)
4

2 回答 2

8

除了 Thomas 的回答之外,您还可以通过覆盖您的类型的记录来告诉您http-conduit不要抛出异常。checkStatusRequest

于 2012-01-27T13:22:03.707 回答
7

您可能应该阅读有关可扩展异常的 Marlow 论文。由 Prelude 导出并在您的代码片段中使用的原始catch仅适用于 IOError。http-conduit 代码正在抛出不同类型的异常,确切地说是HttpException 。(通过 Typeable 类进行了一些动态输入,请参阅论文)。

解决方案?使用Control.Exception中的 catch并仅捕获您要处理的错误类型(或SomeException所有错误类型)。

import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L
import Control.Exception as X

main = do
    let badUrl = "http://www.google.com/intl/en_com/images/srpr/WRONG.png"
    imgData <- (simpleHttp badUrl) `X.catch` statusExceptionHandler
        L.writeFile "my.png" imgData

statusExceptionHandler ::  SomeException -> IO L.ByteString
statusExceptionHandler e = (putStrLn "oops") >> (return L.empty)
于 2012-01-27T03:42:21.863 回答