0

What is a value that I need to return from the getSrc when the http code is unsuccessful and I wish not to create a file (by sinkFile)
If i just return getResponseBody res the http error itself is saved into the file.

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
            ???
1
  • What is that you are trying to do ? Commented Jun 12, 2018 at 6:41

2 Answers 2

2

From what I understand, you want to pipe the response body to some conduit if the response was successful and an alternate conduit in case the response wasn't successful.

I believe that the easiest solution would involve "choosing" a conduit using the if ... then ... else you already have in your code - something like

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

You can replace the yield "an alternate operation" .| printC with another conduit that does what you actually want.

Note that now sinkFile location is only executed in the success case so the failure case doesn't create any files.

Sign up to request clarification or add additional context in comments.

Comments

1

Kartin's solution should work just fine. Another approach you could take would be to use sinkFileCautious instead of sinkFile, and throw a runtime exception on an invalid status code. In fact, you could replace parseRequest with parseUrlThrow to automatically get this behavior.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.