0

I have this piece of code:

router.route("/post")
        .get(function(req, res) {
            ...
        })
        .post(authReq, function(req, res) {
            ...
            // Get uploaded file
            var fstream
            req.pipe(req.busboy)
            req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            ...

            var fileSuffix = mimetype.split("/")[1] // Get suffix, may not always be correct
            var tmpFileName = postCount + "." + fileSuffix
            var tmpFileURL = __dirname + "/tmp/" + tmpFileName
            // Start writing
            fstream = fs.createWriteStream(tmpFileURL)
            file.pipe(fstream)
            fstream.on('close', function() {
                 ...
            })
        })
    })
})

This use to work perfectly. However, I don't know quite what happened, but I picked up my computer today and found this error occurring every time I attempt to post:

TypeError: Cannot call method 'on' of undefined
    at IncomingMessage.Readable.pipe (_stream_readable.js:494:8)
    at /Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:139:8
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at authReq (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:17:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at next (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:94:14)
    at Route.dispatch (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/com~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)

_stream_readable.js:501
    dest.end();
         ^
TypeError: Cannot call method 'end' of undefined
    at IncomingMessage.onend (_stream_readable.js:501:10)
    at IncomingMessage.g (events.js:180:16)
    at IncomingMessage.emit (events.js:92:17)
    at _stream_readable.js:943:16
    at process._tickCallback (node.js:419:13)

In my index.js file, I have this code to use Busboy:

app.use(busboy())

Then this code to include my route:

app.use("/api", require("./apiRoutes.js")())

Thanks in advance!

EDIT: I was doing a bit more debugging and I think I pinpointed the issue. req.busboy is not defined. So I went digging through source code. Here is some of the code in the connect-busboy module:

if (req.busboy
|| req.method === 'GET'
|| req.method === 'HEAD'
|| !hasBody(req)
|| !RE_MIME.test(mime(req)))
return next()

When I print out the actual values, busboy does not exist, the request method is 'POST', hasBody(req) results true, yet RE_MIME.test(mime(req))) results false, which is why busboy is not added to the request.

My example file's MIME type is image/gif. Here is the regular expression connect-busboy is testing image/gif off of (aka RE_MIME variable):

/^(?:multipart\/.+)|(?:application\/x-www-form-urlencoded)$/i;

Therefore, I've come to the verdict I'm misunderstanding the API. Is Busboy only for HTML forms?

EDIT #2: I simply switched to Multer and it works fine. However, I believe my issue was that I needed to place the file in a multipart part of the request; I'm not sure why it was working before. Thanks!

8
  • 1
    What does console.dir(req.headers['content-type']) show? Commented Nov 27, 2014 at 3:25
  • @mscdex NodeJS doesn't seem to show anything for console.dir, but for console.log, it shows "image/gif" and that's it (since I'm attempting to upload a GIF). Commented Nov 27, 2014 at 3:29
  • where is tmpFileURL? I can't see where you declared it Commented Nov 27, 2014 at 4:52
  • @SinaSadrzadeh - Whoops, I accidentally took out that code. I added that code right before // Start writing. The directory does exist, I checked it. Thanks! Commented Nov 27, 2014 at 5:12
  • I just tried reverting to my last commit, but it still doesn't work. I'm wondering if the Busboy library updated or something. I really don't know what to do from here. Commented Nov 27, 2014 at 7:13

2 Answers 2

4

The problem is that your request is not multipart/form-data, but image/gif instead. Busboy, multer, formidable, multiparty, etc. cannot parse the request unless it's multipart/form-data (if you are uploading a file).

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

Comments

1

Make sure you have in your index.js file:

var busboy = require('connect-busboy');
// ...
var app = express();
// ...
// and
app.use(busboy()); // I had exact the same error when this line was missing in index.js

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.