简体   繁体   English

Wreq:停止404s抛出异常

[英]Wreq: Stop 404s throwing exceptions

I am trying to test broken links but, when I use Wreq's get method and run into a 404, I get an exception (see bottom) rather than a statusCode to handle. 我试图测试断开的链接但是,当我使用Wreq的get方法并遇到404时,我得到一个异常(见底部)而不是一个要处理的statusCode。 Only 200s seem to be returned. 似乎只返回了200s。

I tried to follow the error-handling code in the tutorial but I can't find a way to return the same type as get u . 我试图遵循教程中的错误处理代码,但我找不到返回与get u相同类型的方法。 Moreover, this seems to be more complexity than I need in this instance. 而且,这似乎比我在这种情况下需要的更复杂。

How can I simply prevent the exception and just return the responseStatus as is 我怎样才能简单地阻止异常并按原样返回responseStatus

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 e@(StatusCodeException s respHeaders _) =
            do
                return respHeaders

Here is the exception thrown, and you can see it has the stateCode i want 这是抛出的异常,你可以看到它有我想要的stateCode

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

Yuras suggested using options, but I have been unable to work from the example using params to one using checkStatus :: Lens' Options (Maybe StatusChecker) : Yuras建议使用选项,但我无法使用params来使用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

NOTE: the answer is outdated, see other answers. 注意:答案已过时,请参阅其他答案。

I never used Wreq , but it looks like you should use getWith to pass custom options and checkStatus to configure status handling. 我从未使用Wreq ,但看起来你应该使用getWith传递自定义选项和checkStatus来配置状态处理。

An example: 一个例子:

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

The \\_ _ _ -> Nothing is a function to check status code, see StatusChecker . \\_ _ _ -> Nothing是检查状态代码的函数,请参阅StatusChecker It returns nothing indicating that any status code is OK. 它不返回任何指示任何状态代码都正常的内容。

To expand on the answer by Evelyn Schneider, I got this to work with 为了扩展Evelyn Schneider的答案,我得到了这个

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

For posterity: newer versions of wreq (starting with 0.5 ) have replaced checkStatus with checkResponse , which takes different arguments. 对于后代:较新版本的wreq (从0.5开始)已将checkStatus替换为checkResponse ,后者采用不同的参数。 An equivalent to Yuras' answer would now be: 相当于Yuras的回答现在是:

getWith opts url
  where opts = set checkResponse (\_ _ -> return ()) defaults

Here's the checkStatus function I ended up with after researching a bit. 这是我研究了一下之后最终得到的checkStatus函数。 I couldn't figure out how to convert a HttpException to a SomeException , but then I found Control.Monad.Catch.SomeException . 我无法弄清楚如何将HttpException转换为SomeException ,但后来我找到了Control.Monad.Catch.SomeException This will ignore 404s and re-throw all other exceptions. 这将忽略404并重新抛出所有其他异常。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM