Multer unexpected field error handling - node.js

The route with my multer middleware goes something like this.
router.post('my-route-path', multer.single('file'), controllerFunc)
The multer function I have defined is to allow a single file uploaded to the file system. Everything works fine, the issue is if I have define the field name to be file If in my client request I set the field name to be file it works great. But if I give it xyz then it throws an error. Which it should the problem is I can't seem to catch that error, in my catch(e) block of my promise.
This is the error I get
Error: Unexpected field
at makeError (F:\Servup\chat\node_modules\multer\lib\make-error.js:12:13)
at wrappedFileFilter (F:\Servup\chat\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (F:\Servup\chat\node_modules\multer\lib\make-middleware.js:114:7)
at emitMany (events.js:146:13)
at Busboy.emit (events.js:223:7)
at Busboy.emit (F:\Servup\chat\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (F:\Servup\chat\node_modules\busboy\lib\types\multipart.js:213:13)
at emitOne (events.js:115:13)
at PartStream.emit (events.js:210:7)
at HeaderParser.<anonymous> (F:\Servup\chat\node_modules\dicer\lib\Dicer.js:51:16)
at emitOne (events.js:115:13)
at HeaderParser.emit (events.js:210:7)
at HeaderParser._finish (F:\Servup\chat\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (F:\Servup\chat\node_modules\dicer\lib\HeaderParser.js:40:12)
at emitOne (events.js:115:13)
at SBMH.emit (events.js:210:7)
The current implementation that I tried in my catch block was this. (this doesn't work)
catch(e => {
if (e === 'Unexpected field') {
// catch that error here
}
});

You can catch an unexpected field error by doing this
url: https://www.npmjs.com/package/multer
var upload = multer().single('avatar')
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err) {
// An error occurred when uploading
return
}
// Everything went fine
})
})

Related

Getting MulterError: Unexpected field when adding mutiple file in put request

I am working on uploading multiple files for my product. But when i am trying to make a put request with those files, i got an error from multer on runtime
MulterError: Unexpected field
at wrappedFileFilter (G:\GIT\Mern_Eshop\back-end\node_modules\multer\index.js:40:19)
at Busboy.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\multer\lib\make-middleware.js:114:7)
at Busboy.emit (events.js:315:20)
at Busboy.emit (G:\GIT\Mern_Eshop\back-end\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\busboy\lib\types\multipart.js:213:13)
at PartStream.emit (events.js:315:20)
at HeaderParser.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:51:16)
at HeaderParser.emit (events.js:315:20)
at HeaderParser._finish (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:40:12)
at SBMH.emit (events.js:315:20)
at SBMH._sbmh_feed (G:\GIT\Mern_Eshop\back-end\node_modules\streamsearch\lib\sbmh.js:159:14)
at SBMH.push (G:\GIT\Mern_Eshop\back-end\node_modules\streamsearch\lib\sbmh.js:56:14)
at HeaderParser.push (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\HeaderParser.js:46:19)
at Dicer._oninfo (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:197:25)
at SBMH.<anonymous> (G:\GIT\Mern_Eshop\back-end\node_modules\dicer\lib\Dicer.js:127:10)
My code is here
router.put(
'/gallery-images/:id',
uploadOptions.array('images', 10),
async (req, res)=> {
if(!mongoose.isValidObjectId(req.params.id)) {
return res.status(400).send('Invalid Product Id')
}
const files = req.files;
let imagesPaths = [];
const basePath = `${req.protocol}://${req.get('host')}/public/uploads/`;
if(files) {
files.map(file =>{
imagesPaths.push(`${basePath}${file.filename}`);
})
}
const product = await Product.findByIdAndUpdate(
req.params.id,
{
images: imagesPaths
},
{ new: true}
)
if(!product)
return res.status(500).send('the gallery cannot be updated!')
res.send(product);
}
)
Any advice appreciated on where to look ?
This error generally occur when you are sending the name different on Images and using different multer configuration.
uploadOptions.array('images', 10) // check your are sending files with name 'images'
If the name is different, you should put that name instead.

Error not being handled in chain of promises

I am fairly new to Node and am currently trying to tweak an existing project. Part of this uses the follow-redirects package to make HTTP(S) requests to fetch an image.
Occasionally my service crashes with the following trace:
events.js:174
throw er; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (_http_client.js:323:15)
at Socket.socketOnEnd (_http_client.js:426:23)
at Socket.emit (events.js:203:15)
at Socket.EventEmitter.emit (domain.js:448:20)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at ClientRequest.eventHandlers.(anonymous function) (/home/.../node_modules/follow-redirects/index.js:13:24)
at ClientRequest.emit (events.js:198:13)
at ClientRequest.EventEmitter.emit (domain.js:448:20)
at Socket.socketOnEnd (_http_client.js:426:9)
at Socket.emit (events.js:203:15)
[... lines matching original stack trace ...]
at process._tickCallback (internal/process/next_tick.js:63:19)
I assume this means that I am dropping the error which comes back from the HTTP request.
Here is my function where I make the request:
function fetchRemote (imageUrl) {
let options = ...
return new Promise((resolve, reject) => {
https.get(options, resolve);
});
}
And it's called using a chain of promises.
fetchRemote(imageUrl)
.then(getResizeStream)
.then(storeImage)
.then(finished)
.catch(error);
function error (err) {
reject(new Error(`Failed: ${err.message}`));
};
Is there a logic pathway I'm missing, or should this properly catch the error? Or is the issue actually in the follow-redirects package?
Sockets are "event" emitter based and not promises. You need to handle errors on sockets by doing something along the lines of
socket.on('error',function(err){ /* handle error */});
// for you:
https
.get(options, resolve)
.on('error', err => {
reject(err);
});

How can i fix this call back error in Node.js?

At first, I installed this library,
> npm install rocketchat-api
and then I've ran this code to use rocket.chat REST API
// Node.js code
const RocketChatApi = require('rocketchat-api');
const result='https://rocket.chat/docs/developer-guides/rest-api/users/setavatar';
const userId='A user id';
const avatarUrl='http://www.coca.ir/wp-content/uploads/2017/05/flowers-love-profile-pictures-1.jpg'
const rocketChatClient = new RocketChatApi(
'https',
'rocket.chat',
443,
'username',
'password',
(err, result)=>{
console.info('RC connected', result)
});
rocketChatClient.users.setAvatar(userId, avatarUrl, (err, body)=>{
});
After run this in Node.js, I got following error, anyone can help me?
\node_modules\rocketchat-api\lib\net.js:144
return callback ? callback(error, null) : reject(error);
^
TypeError: callback is not a function
at Request.clientRequest [as _callback] (D:\node js projects\rocketTest\node_modules\rocketchat-api\lib\net.js:144:39)
at self.callback (D:\node js projects\rocketTest\node_modules\request\request.js:185:22)
at Request.emit (events.js:198:13)
at ClientRequest.<anonymous> (D:\node js projects\rocketTest\node_modules\request\request.js:819:16)
at Object.onceWrapper (events.js:286:20)
at ClientRequest.emit (events.js:198:13)
at TLSSocket.emitRequestTimeout (_http_client.js:662:40)
at Object.onceWrapper (events.js:286:20)
at TLSSocket.emit (events.js:198:13)
at TLSSocket.Socket._onTimeout (net.js:442:8)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)
That's because setAvatar() only accepts 2 parameters: avatarUrl and callback. If you pass 3 parameters, it would take the second one as callback, and throw TypeError if it is not a function (In your example, the 2nd parameter avatarUrl is a string).
Please refer to the source code of lib/api/users.js in rocketchat-api source code:
setAvatar (avatarUrl, callback) {
return this.client.request("POST", "users.setAvatar", {
avatarUrl
}, callback);
}
Unfortunately, the rocketchat-api module's document is incorrect, which leads the problem.

Cloud Functions for Firebase Image download function Error

I am building a web application using Firebase and the new feature Cloud Functions for Firebase. I have created a function that takes a URL and downloads the image into a 64-bit encoded string as below using the node modules request and request-promise-native:
module.exports = {
downloadImageFromUrl: function (url) {
var options = {
method: 'GET',
uri: url,
resolveWithFullResponse: true,
simple: false,
family: 4
};
return rp.get(options)
.then(function (res) {
return "data:" + res.headers["content-type"] + ";base64," + new Buffer(res.body).toString('base64');
})
.catch(function (error) {
console.log("ERROR GETTING image", error);
return error;
});
}
};
The top function works perfectly running locally but once on firebase it gives the error:
RequestError: Error: getaddrinfo EAI_AGAIN lh6.googleusercontent.com:443
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/user_code/node_modules/request/request.js:188:22)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at Request.onRequestError (/user_code/node_modules/request/request.js:884:8)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at connectErrorNT (net.js:1020:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
I am calling the function in the firebase auth trigger when a user is created as below:
exports.createUser = functions.auth.user().onCreate(event => {
if (event.data.photoURL) {
utils.downloadImageFromUrl(event.data.photoURL)
.then(function(res){
console.log("User Photo", res);
})
.catch(function(error){
console.log("Error", error);
})
}
});
Any help would be greatly appreciated.
Not entirely sure yet if this is the answer, but after reading the documentation, I read their free plan which says you cannot make any out bound requests. So I guess getting an image from a Url counts as an outbound request. After I start paying for their service, I will come back to verify if this was the problem.

Mongoose .save() -- TypeError: _this[i].emit is not a function

When attempting to save a document this error is thrown:
/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
TypeError: _this[i].emit is not a function
at EventEmitter.notify (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/types/documentarray.js:238:18)
at emitOne (events.js:82:20)
at EventEmitter.emit (events.js:169:7)
at Document.(anonymous function) [as emit] (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/document.js:93:44)
at EventEmitter.<anonymous> (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/schema/embedded.js:31:15)
at emitTwo (events.js:92:20)
at EventEmitter.emit (events.js:172:7)
at model.Document.(anonymous function) [as emit] (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/document.js:93:44)
at /Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/model.js:227:11
at /Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/lib/model.js:135:7
at /Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/collection.js:504:5
at /Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/collection.js:666:5
at handleCallback (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/utils.js:96:12)
at /Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:473:9
at handleCallback (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/utils.js:96:12)
at resultHandler (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:420:5)
at commandCallback (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:1246:9)
at Callbacks.emit (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:119:3)
at null.messageHandler (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:397:23)
at Socket.<anonymous> (/Users/home/Documents/web/thp/modules/thp_db/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/connection/connection.js:302:22)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:153:18)
at Socket.Readable.push (_stream_readable.js:111:10)
at TCP.onread (net.js:536:20)
Code leading to save looks like this:
var db = req.app.locals.db;
var league = new db.League();
// league is populated here
// ================
// GIVE LEAGUE _id (auto increment)
// ================
db.Counter.findByIdAndUpdate('League',
{ $inc: { n: 1 } },
{ new: true },
function(err, counter){
if(err) return log.error('League _id set error', err);
league._id = counter.n;
// ================
// INTO DB: CODE RUNS TO HERE
// ================
league.save(function(err, new_league) {
// DOES NOT REACH HERE!
if (err) {
log.error('league DB entry error:', err);
return res.status(200).end('Error creating league');
}
console.log('SAVED LEAGUE', util.inspect(new_league, false, null));
res.status(200).end('Thank you');
});
}
);
Strange thing is that this worked fine last night, and unless I sleepwalked and logged in, nothing was changed.
the db variable is a collection of models.
Any help would be much appreciated.
Turns out that the error is thrown depending on which inputs of the submission form are filled out. Haven't the time to determine which exactly at the moment, but will update here when I do.
UPDATE: my league var was populated by a JSON object parsed from incoming form data. One of the properties was thoughtlessly called .on, which was fooling with the standard event listening notation .on. Silly mistake! Always is.

Resources