2015-12-15 3 views
5

Я пытаюсь проверить неработающие ссылки, но когда я использую метод Wreq get и запускаю в 404, я получаю исключение (см. Ниже), а не код состояния для обработки. Кажется, возвращено только 200 человек.Wreq: исключение исключения для исключения 404s

Я попытался выполнить код обработки ошибок в tutorial, но я не могу найти способ возврата того же типа, что и get u. Более того, это кажется более сложным, чем мне нужно в этом случае.

Как я могу просто предотвратить исключение и просто вернуть 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 [email protected](StatusCodeException s respHeaders _) = 
      do 
       return respHeaders 

Здесь брошено исключение, и вы можете видеть это имеет stateCode я хочу

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

Юрась предложил используя параметры, но я не смог работать с примером, используя 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 

ответ

8

ПРИМЕЧАНИЕ: ответ устарел, см. Другие ответы.

Я никогда не использовал Wreq, но похоже, что вы должны использовать getWith передать дополнительные опции и checkStatus настроить обработку состояния.

Пример:

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

\_ _ _ -> Nothing является функция проверки кода состояния, см StatusChecker. Он не возвращает ничего, указывающее, что любой код состояния в порядке.

+0

Я не достаточно опытен, чтобы получить все, что вы имеете в виду здесь, но проблема в том, что Wreq обрабатывает что-либо другое, чем '200' как исключение, и мне нужно отключить это. –

+0

@SimonH. Я добавил пример – Yuras

+1

. Спасибо, а также за то, что вы не используете операторы infix –

2

Вот функция checkStatus, с которой я закончил, немного исследовав. Я не мог понять, как преобразовать HttpException в SomeException, но затем я нашел Control.Monad.Catch.SomeException. Это будет игнорировать 404s и повторить все другие исключения.

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

Для потомков: новые версии wreq (начиная с 0.5) заменили checkStatus с checkResponse, который принимает различные аргументы. Эквивалент ответа Yuras' теперь будет getWith opts url where opts = set checkResponse (\_ _ -> return()) defaults

2

Чтобы расширить ответ Эвелин Шнайдер, я получил эту работу с

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