我正在尝试下载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)
我的“oops”消息从不打印,而是应用程序崩溃:
StatusCodeException(Status {statusCode = 404,statusMessage =“Not Found”})[(“Content-Type”,“text / html; charset = UTF-8”),(“X-Content-Type-Options” ,“nosniff”),(“日期”,“星期五,2012年1月27日03:10:34 GMT”),(“服务器”,“sffe”),(“内容长度”,“964”),(“ X-XSS-Protection“,”1; mode = block“)]
我做错了什么?
更新
根据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)
答案 0 :(得分:8)
除了Thomas的回答之外,您可以告诉http-conduit
不要通过覆盖checkStatus
类型的Request
记录来抛出异常。
答案 1 :(得分:6)
您应该阅读Marlow paper on extensible exceptions。由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)