I am trying to build a simple file server to receive files from post request with multipart/form-data and I followed the multer tutorial but it seems something is not quite right and it sometimes returns 500 internal server error. The code is in the following.
var express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = express();
var storage = multer.diskStorage({
destination: function (req, file, cb) {
var dir = 'file/' + req.body.jobid + '/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
});
cb(null, dir);
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage: storage });
app.post('/', upload.single("file"),function (req, res, next) {
res.status(200).end();
next(req,res);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
The error happens like every two requests out of ten.
The code I used to start forever
forever start app.js;
I am new to nodejs and this kind of errors (errors that happen occasionally) is killing me.
I added some functions to log the possible errors.
app.use(function(err, req, res, next) {
console.error(err.stack);
next(err);
});
app.use(function(err, req, res, next) {
if (req.xhr) {
res.status(500).send({ error: err.stack });
} else {
next(err);
}
});
and it logged something like this:
Upload: saved to file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123
Error: ENOENT, open 'file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123'
at Error (native)
Error: ENOENT, open 'file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123'
at Error (native)
What is likely happening, is that sometimes your code is throwing a synchronous error, which express by default will turn into a 500 response. It's pretty difficult to diagnose without knowing what the error is. What you should do is add an error handler before var server
, which will catch errors and log them to console. Then when the error occurs, you'll easily be able to see it and fix the issue.
app.use(function(err, req, res, next) {
console.log(err);
next(err);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
EDIT
Move the line cb(null, dir);
up a line, as such:
destination: function (req, file, cb) {
var dir = 'file/' + req.body.jobid + '/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
// move cb to here
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}