Mongoose CastError - node.js

I have the following code, which does absolutely nothing, and for some reasons, I have an error with mongoose which is not even called, here's the code:
.post('/testRequest', express.json(), upload.none(), async (req, res) => {
try {
res.status(200);
res.send('test');
} catch (err) {
console.error(err.stack);
res.status(err.code || 400);
res.send(err.message || err);
}
})
And here's the error:
message: 'Cast to ObjectId failed for value "test" at path "_id" for model "Requests"',
name: 'CastError',
stringValue: '"test"',
kind: 'ObjectId',
value: 'test',
path: '_id',
reason: undefined,
I've tried many things but didn't seem to fix it

You probably have a .post(':id', ...) on top of your code. So a post request to /testRequest matches the '/:id' and '/testRequest' routes, but only the top one executes.
The ':id' route reads testRequest as an ID and throws the CastError.
You can swap the order of the methods, which was already discussed here.

Related

express.js handle any error in global level

express.js code handle any global error
app.use((err, req, res, next) => {
if (!err) {
return next();
}
res.status(500);
res.send("500: Internal server error");
});
I have above code to handle global error and send silent response without crashing entire app
but still app is crashing . Is it correct way to handle any error ?
app listening on port: 5600
/Users/soubhagyapradhan/Desktop/upwork/cnox/cnoxbackend/node_modules/mongoose/lib/query.js:4678
const castError = new CastError();
^
CastError: Cast to ObjectId failed for value "62626524a4722bf9b398d8f5ddd" (type string) at path "_id" for model "customer"
at model.Query.exec (/Users/soubhagyapradhan/Desktop/upwork/cnox/cnoxbackend/node_modules/mongoose/lib/query.js:4678:21)
at model.Query.Query.then (/Users/soubhagyapradhan/Desktop/upwork/cnox/cnoxbackend/node_modules/mongoose/lib/query.js:4777:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
messageFormat: undefined,

how did this forked in the rest api route go wrong?

Update: This problem was solved. I followed the advice of the replies and tried the console.log(req.body) command. Turns out it was calling a different function. Now at the time I was using postman to test the API and I learned that editing an already saved function is not the same as with other text or media editors and you have to make a completely new function to test it. I.E. I used a previous post function to create user and changed some elements, turns out postman doesnt like that and just ran the old function.
Thanks for the help everyone
I made an admin route using an already working user route exactly except using fewer values.
I keep getting an undefined error during validation when ever I try to run a post function. what could have gone wrong here? Or where should I look for the error, I checked the spellings of each of the values Iam using in the create admin function but I see no spelling problems?
Error in Console:
Error: admin validation failed: AdminEMail: Path `AdminEMail` is required., AdminPassword: Path `AdminPassword` is required.
at ValidationError.inspect (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\error\validation.js:48:26)
at formatValue (internal/util/inspect.js:563:31)
at inspect (internal/util/inspect.js:221:10)
at formatWithOptions (internal/util/inspect.js:1693:40)
at Object.Console.<computed> (internal/console/constructor.js:272:10)
at Object.log (internal/console/constructor.js:282:61)
at D:\Downloads\Compressed\api-master_3\api-master\routes\Admin.js:25:21
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:4876:16
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\helpers\promiseOrCallback.js:16:11
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:4899:21
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\model.js:493:16
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:246:48
at next (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:167:27)
at next (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:169:9)
at Kareem.execPost (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:217:3)
at _handleWrapError (D:\Downloads\Compressed\api-master_3\api-master\node_modules\kareem\index.js:245:21) {
errors: {
AdminEMail: ValidatorError: Path `AdminEMail` is required.
at validate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1178:13)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1161:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1106:14)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\document.js:2379:18
at processTicksAndRejections (internal/process/task_queues.js:76:11) {
properties: [Object],
kind: 'required',
path: 'AdminEMail',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
},
AdminPassword: ValidatorError: Path `AdminPassword` is required.
at validate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1178:13)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1161:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate (D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\schematype.js:1106:14)
at D:\Downloads\Compressed\api-master_3\api-master\node_modules\mongoose\lib\document.js:2379:18
at processTicksAndRejections (internal/process/task_queues.js:76:11) {
properties: [Object],
kind: 'required',
path: 'AdminPassword',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'admin validation failed'
}
And Here is the route:
//Imported modules
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
//Imported models
const Admin = require('../models/admin');
//const User = require('../models/user');
router.get('/', (req,res) =>{
res.send("We are on Admin");
})
//Admin Functions
//Creation of new Admin
router.post("/signup", (req,res) => {
const admin = new Admin({
_id: new mongoose.Types.ObjectId(),
AdminEMail: req.body.AdminEMail,
AdminPassword: req.body.AdminPassword
});
admin.save(function(err,admin){
if(err){
console.log(err);
res.send(err);
return
}
console.log("New admin created");
res.send(admin);
})
})
//Admin Login and verification
router.post("/login", (req,res) => {
const AdminID = req.body.AdminID;
const Username = req.body.username;
const Password = req.body.password;
Admin.findOne({_id:AdminID}, function(err, foundAdmin){
if(err){
res.send("<h1>got clicked</h1>");
console.log(err);
}else{
if(foundAdmin){
if(foundAdmin.AdminEMail === Username){
if(foundAdmin.AdminPassword === Password){
res.send("logged in");
}
else{
res.send("Username and Password Mismatch");
}
}
else{
res.send("Username and ID Mismatch");
}
}
else{
res.send("No Such admin exists");
}
}
});
});
//
module.exports = router;

How to implement Joi validation in hapi.js?

I just want to implement Joi in Hapi API.
server.route([
{
method: 'POST',
path: '/login',
config: {
tags: ['login', 'auth'],
auth: false,
validate: {
payload: payloadValidator,
failAction: (req, h, source, error) => {
console.log("Error ::: ", source.details[0].message);
return h.response({ code: 0, message: source.details[0].message });
}
}
},
handler: async (request, h) => {
console.log(request.payload.email);
console.log(request.payload.password);
...
}
}
]);
Hear I call payloadValidator.
const payloadValidator = Joi.object({
email: Joi.string().required(),
password: Joi.string().required()
}).options({ allowUnknown: true });
Actually I'm new with hapi and I'm missing something in my code. Can anyone help me to fix this issue?
Required output
If I do not pass email then the app must throw an error of Email is required and it should be the same with the password field also.
Error:
Error ::: "email" is required
Debug: internal, implementation, error
Error: Lifecycle methods called before the handler can only return an error, a takeover response, or a continue signal
at Request._lifecycle (/var/www/html/hapi/node_modules/#hapi/hapi/lib/request.js:326:33)
at process._tickCallback (internal/process/next_tick.js:68:7)
As an error suggests Lifecycle methods called before the handler can only return an error, a takeover response, or a continue signal you have to return takeover response.
return h.response({ code: 0, message: source.details[0].message }).takeover();
For more information you can visit this link : reference link

How to use express-winston and winston-mongodb together?

I'm using express-winston and winston-mongodb to log express requests to mongodb.
express-winston config:
expressWinston.logger({
meta: true,
//...other unrelated config
})
winston-mongodb config:
new MongoDB({
//...other unrelated config
})
Logging to mongodb works, but meta field is null. Logging to file/console works perfectly.
The mongo plugin doesn't recognize the express plugin's log format.
How can I get them to play nice?
When you look at the express-winston and winston-mongodb codes, you can easily see the difference.
winston-mongodb writes the value that matches the metaKey field to the specified collection.
Therefore, if you define it as follows, the meta field will not be null.
...
transports: [
new winston.transports.Console({
format: winston.format.json({
space: 2
})
}),
new winston.transports.MongoDB({
db: config.db.mongooseURI,
options: config.db.options,
collection:'logs',
capped:true,
metaKey:'meta'
}),
],
meta: true,
...
This is what finally worked for me: v6.12.1 Noticed later that while this works for db logging, the meta is empty for the file transport. Not sure why.
const winston = require('winston');
module.exports = function(err, req, res, next) {
winston.error(err.message, {metadata: { prop: err } });
res.status(500).send('Something failed.');
};
If you want to log to File and MongoDB then:
winston.add(
new winston.transports.MongoDB({
db: process.env.CONNECTIONSTRING,
options: { useUnifiedTopology: true },
metaKey: 'meta'
})
)
module.exports = function (err, req, res, next) {
// Log the exception
winston.error({message: err.message, level: err.level, stack: err.stack, meta: err})
res.status(500).send("Something failed..Cannot connect to Server");
};

Using the docs but completely confused... mongoose Model#save

I am trying to return specific status codes such as, 409 Conflict. I have used the Model#save docs
Edit: I am not trying to solve the error, it is deliberate.
According to the docs, there is three parameters on the callback: err, product, and numAffected.
EDIT: I wrote this code wrong and I edited. Either way, I got an excellent answer from Ryan.
app.post('/skill', (req, res) => {
const skill = new Skill({some_duplicate_object});
skill.save((err, product, numAffected) => {
console.log("Error: ", err);
});
NOT my console.log, in the Mocha test cli, I get an error:
(node:19760) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 5): ValidationError: Path `name` is required.
By playing around and shear luck, I did this: This is NOT in the mongoose docs and is my main reason for writing this post.
app.post('/skill', (req, res) => {
const skill = new Skill({});
skill.save()
.then((err, product, numAffected) => {
console.log("Nothing displayed here");
}, (err) => {
console.log(err.errors);
});
Even though this is not in the docs, it shows the error I want. As someone that is REALLY trying to use official docs more, I find it so hard to understand what is really going on. Why does this work and if it is in the docs, where would this info be?
{ name:
{ MongooseError: Path `name` is required.
at ValidatorError (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/error/validator.js:24:11)
at validate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:706:13)
at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:752:11
at Array.forEach (native)
at SchemaString.SchemaType.doValidate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:712:19)
at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/document.js:1408:9
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
message: 'Path `name` is required.',
name: 'ValidatorError',
properties:
{ type: 'required',
message: 'Path `{PATH}` is required.',
validator: [Function],
path: 'name',
value: undefined },
kind: 'required',
path: 'name',
value: undefined,
reason: undefined } }
Extra info:
"devDependencies": {
"chai": "^3.5.0",
"mocha": "^2.4.5",
"request": "^2.81.0",
"supertest": "^3.0.0"
},
"dependencies": {
"body-parser": "^1.17.1",
"express": "^4.15.2",
"mongoose": "^4.9.2"
}
Your problem is two fold, and both of the errors you are getting are telling you exactly what is wrong. The source of your troubles is lack of understanding (not trying to pick on you). This is kind of the same as if you were a beginner at electronics and I told your that a tube is biased improperly and you said "I don't understand" - well, you need to learn about tubes then because I just described to you the exact problem with your circuit.
1. Promise error - UnhandledPromiseRejectionWarning: Unhandled promise rejection.... This cannot be more descript. Promises are either 1) resolved or 2) rejected. If you fail to "handle" the rejected case, you will get an error. Handling a rejected promise can happen one of two ways:
// pass a 2nd function to `.then()`:
somePromise.then(function (result) {
// promise was "resolved" successfully
}, function (err) {
// Promise was "rejected"
});
// use `.catch()` - this is preferred in my opinion:
somePromise.then(function (result) {
// promise was "resolved" successfully
}).catch(function (err) {
// Promise was "rejected"
});
Using either of the above scenarios means you "handled" the promise rejection correctly.
2. Database validation - Path 'name' is required.. This literally means that you have a required path called "name" which is required (meaning, it must have a value). So looking at your code it's pretty obvious:
const skill = new Skill({});
skill.save() //-> results in error
This is fixed by adding all required data before saving:
const skill = new Skill({ name: "Jason" });
skill.save() //-> yay, no error
You're not handling the promise rejection.
Change this:
.then((err, product, numAffected) => {
console.log("Error: ", err);
});
to this:
.then((result) => {
console.log('Result:', result);
}).catch((error) => {
console.log('Error:', error);
Of course change what happens in the callbacks to whatever you need.
See this answer for more general info on unhandled rejection:
Should I refrain from handling Promise rejection asynchronously?

Resources