[英]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.