How to properly handle timeouts that occur during streaming, in Nodejs?

Viewed 424

There are various posts dealing with the general issue of timeouts when using http.get(), but non of them seems to address the question of how to deal with timeouts that occur during the stream itself, after a successful response was already received.

Take this code for example. It sends a request to some server, that responds on time, but creates an artificial timeout during the stream:

(async()=>{
    //Send request to a dummy server, that creates a timeout, IN THE MIDDLE OF THE STREAM.
    const request =http.get('http://localhost/timeout/',async (res)=>{
        const write = fs.createWriteStream('.text.txt');
        try {
           await pipelinePromisified(res,write); 
           console.log('Everything went fine')//Being that the timeout error during the stream is not caught by pipeline,
           //the promise gets resolved..
        } catch (error) {
            //The error is NOT caught by pipeline!
            console.log('Error from pipeline',error)
        }
    }).on('error',(e)=>{
        //Error is caught here
        console.log('error from request on error')
    })
    request.setTimeout(4000,()=>{       
        request.destroy(new Error('request timed out'));
        //This causes the piping of the streams to stop in the middle(resulting a partial file), but the pipeline doesn't treat this is an error.
    })

})() 

Note the key issue: The timeout during the stream is recognized, the request is destroyed, the IncomingMessage(response) stops pumping data- but pipeline doesn't recognize it as an error.

The outcome is, that the client code is not aware of the fact that file was partially downloaded, being that no error is thrown.

How to handle this situation? In my testing, calling response.emit('error') seems to solve this, but Node's docs clearly state not to do this.

Any help would be greatly appreciated.

Update: It seems that on Node 12(i have 10 and 12 installed via nvm), an error is caught by pipeline, but not in Node 10.

0 Answers
Related