2012-01-27 4 views
6

के सरल एचटीपी द्वारा फेंकने वाले 404 स्टेटस अपवाद को कैसे पकड़ सकता हूं, मैं एक HTML फ़ाइल में निहित सभी पीएनजी फ़ाइलों को डाउनलोड करने का प्रयास कर रहा हूं। मुझे 404 स्टेटस अपवादों को पकड़ने में परेशानी है, इसके बजाय मेरा प्रोग्राम बस दुर्घटनाग्रस्त हो जाता है।मैं Http.Conduit

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 (स्थिति {statusCode = 404, statusMessage = "नहीं मिला "}) [(" सामग्री-प्रकार "," पाठ/एचटीएमएल; वर्णसेट = यूटीएफ -8 "), (" एक्स-कंटेंट-टाइप-ऑप्शन "," नोस्निफ "), (" तिथि "," शुक्र, 27 जनवरी 2012 03:10:34 जीएमटी "), (" सर्वर "," एसएफएफ "), (" सामग्री-लंबाई "," 9 64 "), (" एक्स-एक्सएसएस-प्रोटेक्शन "," 1; मोड = ब्लॉक ")]

मैं क्या गलत कर रहा हूँ?

अद्यतन:

थोमा की सलाह के बाद, मैं निम्नलिखित स्निपेट के लिए अपने कोड बदल गया है और अब जगह में उचित अपवाद संचालन की है।

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) 

उत्तर

6

आपको शायद Marlow paper on extensible exceptions पढ़ना चाहिए। मूल catch, प्रीलूड द्वारा निर्यात किया गया और आपके कोड स्निप में उपयोग किया गया, केवल IOError के लिए काम करता है। Http-conduit कोड सटीक होने के लिए HttpException के अपवादों को फेंक रहा है। (टाइप करने योग्य वर्ग के माध्यम से कुछ गतिशील टाइपिंग चल रही है, पेपर देखें)।

समाधान? Control.Exception से पकड़ का उपयोग करें और केवल उन त्रुटि प्रकारों को पकड़ें जिन्हें आप संभालना चाहते हैं (या उन सभी के लिए 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) 
+0

धन्यवाद, जिसने मेरी समस्या हल की। मैं केवल विशिष्ट अपवादों को पकड़ने के साथ सहमत हूं (यह मेरा अगला कदम था, मैं अभी वहां कभी नहीं मिला)। –

8

थॉमस के जवाब देने के लिए इसके अलावा, आप http-conduit बता अपने Request प्रकार के checkStatus रिकॉर्ड अधिभावी द्वारा एक अपवाद नहीं फेंक सकता है।

+0

आपने अपना दिन सामान्य रूप से बनाया है (: –