передача потока http в файл (sinkFile), избегайте создания файла, когда http возвращает ошибку - PullRequest
0 голосов
/ 11 июня 2018

Какое значение мне нужно вернуть из getSrc, когда http-код неудачен, и я желаю не создать файл ( sinkFile )
Если япросто верните getResponseBody res сама ошибка http сохраняется в файл.

downloadURL :: String -> FilePath -> IO ()
downloadURL url location = do
  request <- parseRequest url
  runResourceT
         $ runConduit$  httpSource request getSrc
         .| sinkFile location
   where
     getSrc res = do
         let success = statusIsSuccessful . getResponseStatus $ res
         if success then
            getResponseBody res
         else
            ???

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Решение Kartin должно работать просто отлично.Другой подход, который вы могли бы использовать, это использовать sinkFileCautious вместо sinkFile и выдать исключение времени выполнения для недопустимого кода состояния.Фактически, вы можете заменить parseRequest на parseUrlThrow, чтобы автоматически получить это поведение.

0 голосов
/ 12 июня 2018

Насколько я понимаю, вы хотите направить тело ответа к некоторому каналу, если ответ был успешным, и альтернативному каналу в случае, если ответ не был успешным.

Я считаю, что самое простое решение будет включать«выбирая» канал, используя if ... then ... else, который у вас уже есть в вашем коде - что-то вроде

module Main where

import Conduit ( printC
               )
import Data.Conduit ( runConduitRes
                    , (.|)
                    , yield
                    )
import Data.Conduit.Binary ( sinkFile
                           )
import Network.HTTP.Simple ( parseRequest
                           , httpSource
                           , getResponseStatus
                           , getResponseBody
                           )
import Network.HTTP.Types.Status ( statusIsSuccessful
                                 )

main :: IO ()
main = do
  requestText <- init <$> readFile "notes/request.txt"
  downloadURL requestText "notes/sink.txt"

downloadURL :: String -> FilePath -> IO ()
downloadURL url location = do
  request <- parseRequest url
  runConduitRes (httpSource request processResponse)
    where
  processResponse response =
    if statusIsSuccessful (getResponseStatus response)
    then (getResponseBody response) .| sinkFile location 
    else yield "an alternate operation" .| printC

. Вы можете заменить yield "an alternate operation" .| printC другим каналом, который делает то, что вы на самом деле хотите.

Обратите внимание, что теперь sinkFile location выполняется только в случае успеха, поэтому в случае сбоя файлы не создаются.

...