2015-12-15 20 views
5

Tôi đang cố gắng kiểm tra các liên kết bị hỏng nhưng khi tôi sử dụng phương thức get của Wreq và chạy vào 404, tôi nhận được ngoại lệ (xem dưới) thay vì mã trạng thái để xử lý. Chỉ có 200s dường như được trả lại.Wreq: Dừng 404s ném ngoại lệ

Tôi đã cố gắng làm theo mã xử lý lỗi trong tutorial nhưng tôi không thể tìm cách trả về cùng một loại như get u. Hơn nữa, điều này có vẻ phức tạp hơn tôi cần trong trường hợp này.

Làm thế nào tôi có thể chỉ đơn giản là ngăn chặn sự ngoại lệ và chỉ trả lại responseStatus như là

verifySeatme :: Maybe URL -> IO UrlStatus 
verifySeatme url = do 
    case url of 
     Nothing -> return None 
     Just "" -> return None 
     Just u -> do 
      seatmeResp <- get u --`E.catch` handler 
      -- r ^? responseBody . key "url" 
      -- could also check for redirect to errorPage.aspx 
      if seatmeResp ^. W.responseStatus . statusCode == 200 
      then return (Working u) 
      else return Broken 
    where 
     handler [email protected](StatusCodeException s respHeaders _) = 
      do 
       return respHeaders 

Dưới đây là ngoại lệ ném ra, và bạn có thể thấy nó có stateCode tôi muốn

*Main> re <- get "https://www.seatme.nl/restaurant/1371/Londen.htm" 
*** Exception: StatusCodeException (Status {statusCode = 404, statusMessage = "Not Found"}) [("Cache-Control","private"),.... 

Yuras gợi ý sử dụng các tùy chọn, nhưng tôi không thể làm việc từ ví dụ này bằng cách sử dụng params cho một người sử dụng checkStatus :: Lens' Options (Maybe StatusChecker):

getData :: IO Restos 
getData = do 
    let opts = defaults & customStatusHandler 
    jdata <- asJSON =<< getWith opts "http://localhost/restos-short.json" :: IO Resp 
    let 
     restos = jdata ^. W.responseBody 
    verified <- mapM processEntry restos 
    return verified 

-- type StatusChecker = Status -> ResponseHeaders -> CookieJar -> Maybe SomeException 
customStatusHandler :: W.StatusChecker 
customStatusHandler st res _ = 
    Just res 

Trả lời

8

LƯU Ý: câu trả lời đã lỗi thời, hãy xem các câu trả lời khác.

Tôi chưa bao giờ sử dụng Wreq, nhưng có vẻ như bạn nên sử dụng getWith để chuyển tùy chọn tùy chỉnh và checkStatus để định cấu hình xử lý trạng thái.

Một ví dụ:

getWith (set checkStatus (Just $ \_ _ _ -> Nothing) defaults) 
    "http://google.com/hello/world" 

Các \_ _ _ -> Nothing là một chức năng để kiểm tra mã trạng thái, xem StatusChecker. Nó trả về không có gì chỉ ra rằng bất kỳ mã trạng thái nào là OK.

+0

Tôi không đủ kinh nghiệm để có được tất cả những gì bạn có nghĩa là ở đây, nhưng vấn đề là Wreq đang xử lý bất kỳ điều gì khác ngoài '200' làm Ngoại lệ và tôi cần phải tắt số –

+0

@SimonH tôi đã thêm một ví dụ – Yuras

+1

Cảm ơn và cảm ơn bạn vì không sử dụng toán tử infix –

2

Đây là hàm checkStatus mà tôi đã kết thúc sau khi nghiên cứu một chút. Tôi không thể tìm ra cách chuyển đổi một số HttpException thành SomeException, nhưng sau đó tôi tìm thấy Control.Monad.Catch.SomeException. Điều này sẽ bỏ qua 404 và tái ném tất cả các ngoại lệ khác.

import   Network.HTTP.Client.Types 
import   Network.HTTP.Types.Status 
import   Network.HTTP.Types.Header 
import qualified Control.Exception as E 
import   Control.Monad.Catch (SomeException(..)) 

notFoundMeansNothing :: Status -> ResponseHeaders -> CookieJar -> Maybe E.SomeException 
notFoundMeansNothing s h c 
    | s == status404 = Nothing 
    | otherwise = 
     if statusIsClientError s || statusIsServerError s then 
      Just . SomeException $ StatusCodeException s h c 
     else 
      Nothing 
2

Đối với hậu thế: phiên bản mới hơn của wreq (bắt đầu với 0.5) đã thay thế checkStatus với checkResponse, trong đó có lập luận khác nhau. Tương đương với Yuras' câu trả lời bây giờ sẽ là getWith opts url where opts = set checkResponse (\_ _ -> return()) defaults

2

Mở rộng trên câu trả lời của Evelyn Schneider, tôi nhận được điều này để làm việc với

r <- getWith opts url 
where 
    opts = set Network.Wreq.checkResponse (Just $ \_ _ -> return()) defaults