これは、公式の例checkStatus
の 1 つに似たカスタムを使用することで可能になります。
応答ステータス コードが 2xx または 404 の場合、どちらがパスするかを宣言します。checkStatus200
パスしない場合は、デフォルトcheckStatus
関数を呼び出して適切な例外をスローします。
usingで呼び出しhttpLbs
た後、ステータス コードを確認して、レスポンス コードまたはを返すことができます。Request
checkStatus200
Just
Nothing
import Data.Conduit.Binary (sinkFile)
import Network.HTTP.Types.Status (Status(..))
import Network.HTTP.Conduit
import qualified Data.Conduit as C
import Network
import Data.Default (def)
import qualified Data.ByteString.Lazy as LB
-- | @checkStatus@ implementation that accepts
-- 2xx status codes and 404. Calls default implementation
-- on other status codes (i.e. throws exception)
checkStatus200 st@(Status sc _) rh cj =
if (200 <= sc && sc < 300) || sc == 404
then Nothing
else (checkStatus def) st rh cj
-- | Download a HTTP link, returning @Nothing@ on 404 status code
downloadCatch404 :: String
-> IO (Maybe LB.ByteString)
downloadCatch404 url = withSocketsDo $ do
request <- parseUrl url
let request' = request { checkStatus = checkStatus200 }
res <- withManager $ httpLbs request'
let status = statusCode . responseStatus $ res
-- Return Nothing if status code == 404
return $ if status == 404
then Nothing
else Just $ responseBody res