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; 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)
4

2 に答える 2

8

トーマスの答えに加えて、自分のタイプのレコードをhttp-conduitオーバーライドすることで、例外をスローしないように指示できます。checkStatusRequest

于 2012-01-27T13:22:03.707 に答える
7

おそらく、拡張可能な例外に関するMarlowの論文を読む必要があります。catchPreludeによってエクスポートされ、コードsniptで使用されるオリジナルは、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 に答える