I’ll be grateful if you can help me understand an error generated by mongoose.
Log Error:
TypeError: Cannot read properties of undefined (reading 'name')
at Object.isPOJO (C:Users[...]node_modulesmongooselibutils.js:396:38)
at Object.toObject (C:[...]node_modulesmongooselibutils.js:354:15)
at model.Query.Query.find (C:[...]node_modulesmongooselibquery.js:2341:22)
at Function.find (C:[...]node_modulesmongooselibmodel.js:2244:13)
at Object.exports.findMatches (C:[...]controllersmatches.js:13:11)
at preHandlerCallback (C:[...]node_modulesfastifylibhandleRequest.js:128:37)
at preValidationCallback (C:[...]node_modulesfastifylibhandleRequest.js:112:5)
at handler (C:[...]node_modulesfastifylibhandleRequest.js:76:7)
at handleRequest (C:[...]node_modulesfastifylibhandleRequest.js:24:5)
at runPreParsing (C:[...]node_modulesfastifylibroute.js:522:5)
The point is I wasn’t working on anything related Mongoose. I’ve just realized it’s happening (all of a sudden, the code was working fine a while ago) only when I use dates in my query (query sample: {startDate: { $gt: new Date(req.query.date)} }
: req.query.date
is a ISO string date). Now I get the above error in every query regarding dates, while they were working fine.
Mongoose code generating the error is the following:
exports.isPOJO = function isPOJO(arg) {
if (arg == null || typeof arg !== 'object') {
return false;
}
const proto = Object.getPrototypeOf(arg);
// Prototype may be null if you used `Object.create(null)`
// Checking `proto`'s constructor is safe because `getPrototypeOf()`
// explicitly crosses the boundary from object data to object metadata
return !proto || proto.constructor.name === 'Object';
};
As a test, if I change proto.constructor.name
to proto.constructor?.name
resolves the error and everything works fine, but the goal is to understand what’s going on, not messing up with a dependency code.
If it’s relevant, I’m using Fastify in this application.
2
Answers
It appears the issue was relative to query string parsing. Solved by passing explicitly the querystringParser parameter to Fastify:
Note: querystringParser is usually used to change the default parser or changing the default behaviour. I'm not sure why in my istance I'm needing to set explicitally.
Official Fastify documentation about querystringParser:
Thanks everyone for answers!
The mongoose
isPOJO
code doesn’t work for objects that don’t inherit theObject
prototype.As you mentioned query strings,
querystring.parse()
returns objects without theObject
prototype so those defaultObject
properties can’t clash with incoming query parameters.Maybe raise the issue in mongoose if you think this use is valid.
A work around is to reconstruct the object being passed through if you are not concerned about request params with the prototype names: