Closed gkostov closed 2 hours ago
how to tell busboy code to stop processing without crashing the application
Stop writing data to the busboy instance or add an 'error'
event handler to the busboy instance.
Adding the error
event handler seems to prevent the exception from crashing the application. Thanks for that.
Though, I still don't know exactly what you mean by "Stop writing data to the busboy instance". When the client disappears then there is no more data written to the instance but busboy is still there and waiting for more. Given that busboy is piping from the Request object I thought that destroying the request (with req.destroy();
) would make it obvious that busboy has nothing more to work on, but nope - busboy is still there and waiting for more. Only after req.busboy.destroy();
it will close down the file stream and itself (I guess its own stream gets GC'ed, but I haven't checked that). So my final code became:
let outputFileStream = fs.createWriteStream(localFileName);
file.on('error', err => outputFileStream.destroy(err) );
req.setTimeout(1000, () => {
req.destroy(); // terminate the request so the socket is freed
req.busboy
.on('error', () => {}) // this is being set just to prevent the exception from crashing the application
.destroy();
});
file.pipe(outputFileStream);
Do you think it is worth mentioning this caveat in the docs? I've seen a lot of examples doing what the docs say and not considering how file and socket handles will leak along with the disk space for broken uploads? I can setup a PR if you think it can be of any benefit for others.
Cheers
Hi,
I believe I am in a similar situation to https://github.com/mscdex/busboy/issues/366 - in my case I need to abort the request because the client has gone away (connection broken, etc.). I am piping the file data as per the examples like:
and when the client stops sending data the connection simply remains hanging around forever (both the socket and the output file handles, and uploaded file data on the disk remain, piling up to thousands with time until the app is restarted).
I'm using node@20 and Express@4 and there does not appear to be any default timeouts on the server's requests. So I tried setting a timeout on the server (which each request properly inherited) but, as per the documentation, what happens is:
So other than a "timeout" event firing on the socket there is nothing else happening and the connection and file handles remain.
To be able to monitor what is happening, I extended the example's code to this:
I was hoping that
req.destroy();
will kill the request which, as you've suggested in https://github.com/mscdex/busboy/issues/366, will make it "stop writing to the busboy stream". The client browser sees the connection as terminated but busboy does not and nothing more happens after the console prints:Now I thought that maybe busboy isn't notified of the connection termination so I need to manually tell it to stop and changed this code to:
Which appears to be closing the busboy stream and my output stream, but it also crashes the application with these logs:
And now I'm out of ideas for how to tell busboy code to stop processing without crashing the application? Could you help with this, please?
Thanks a lot