I'm implementing file upload with Node.js and my code works fine with normal case.
However, when I made it fail to write a file (for example, writing it to non-existing directory), it calls error handler, fstream.on('error', ...)
, but it gets stuck and never proceed.
I was assuming that by unpiping the incoming stream, busboy
moves on to the next part of processing, but it seems like it was not the case.
I'd like to run same busboy.on('end')
to respond to the browser (with some error info), but how can I get this called?
var express = require("express");
var Busboy = require('busboy');
var fs = require('fs');
var upload = require('./upload');
var Path = require('path');
var app = express();
app.get("/", function(request, response) {
response.writeHead(200, { Connection: 'close'});
response.end('<html><body>' +
'<form action="/upload" method="post" enctype="multipart/form-data">' +
' <input type="file" name="filefield">' +
' <input type="submit">' +
'</body></html>');
});
app.post("/upload", function(request, response) {
// request.files will contain the uploaded file(s),
// keyed by the input name (in this case, "file")
console.log(request.body);
var fileId = upload.generateId();
var busboy = new Busboy({headers: request.headers});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
var path = Path.join('images', fileId);
console.log('hello');
var fstream = fs.createWriteStream(path);
fstream.on('end', function() {
console.log("EOF");
});
fstream.on('close', function() {
console.log("CLOSE");
});
fstream.on('error', function(err) {
console.log("ERROR:" + err);
file.unpipe();
fstream.end();
});
fstream.on('finish', function() {
console.log('onFinish');
})
file.on('end', function() {
console.log('file end');
});
file.pipe(fstream);
});
busboy.on('end', function() {
console.log('busboy end');
response.json({id:fileId});
});
request.pipe(busboy);
});
app.listen(3000);
The function fs. createWriteStream() creates a writable stream in a very simple manner. After a call to fs. createWriteStream() with the filepath, you have a writeable stream to work with. It turns out that the response (as well as the request) objects are streams.
You don't need a readable stream instance, just use res. write() : res. write("USERID,NAME,FBID,ACCOUNT,SUBSCRIPTION,PRICE,STATE,TIMEPERIOD\n"); for (var i = 0; i < 10; i++) { res.
PassThrough. This Stream is a trivial implementation of a Transform stream that simply passes the input bytes across to the output. This is mainly for testing and some other trivial use cases. Here is an example of Passthrough Stream where it is piping from readable stream to writable stream.
pipe() method in a Readable Stream is used to attach a Writable stream to the readable stream so that it consequently switches into flowing mode and then pushes all the data that it has to the attached Writable.
I solved the issue by placing file.read()
in 'error'
event handler.
fstream.on('error', function(err) {
console.log("ERROR:" + err);
file.read();
});
When createWriteStream
had an error, error
handler is called and pipe connection is broken up (unpiped
), but incoming stream (file
) has unread data in the stream and that hasn't consumed.
By calling .read()
, it is read (but not delivered to Writable stream because no one is listening to) and end
event is emit to the reader. This triggers busboy.on('end')
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With