express.js handle any error in global level - node.js

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,

Related

How can we get & post request of same model object at same route at same time?

I am new to nodejs and i just started learning..I am trying to show the form data in table at
same time without restarting the server ..I need to update the changes at runtime
Below is the code of index.js where i have created routes,get and post request.
**var express = require('express');
var empModel = require('../modules/employee') //importing model object
var router = express.Router();
var employee = empModel.find({}); //storing model object in employee
/* GET home page. */
router.get('/', function(req, res, next) {
employee.exec(function(err,data){
if (err) throw err;
res.render('index', { title: 'Employee records' , records:data });
})
});
//post request of form
router.post('/', function (req, res, next) {
var empDetails = new empModel({
name : req.body.ename,
email : req.body.eemail,
etype : req.body.eetype,
hourlyrate : req.body.ehourrate,
totalhour : req.body.etotalhour,
total : parseInt(req.body.ehourrate) * parseInt(req.body.etotalhour) ,
})
empDetails.save(function(err,res1){
if(err) throw err;
employee.exec(function(err,data){
if (err) throw err;
res.render('index', { title: 'Employee records' , records:data });
})
});
});
module.exports = router;**
on staring the server error is :
PS C:\Users\harsh\Desktop\Employee> npm start
npm WARN config global --global, --local are deprecated. Use --location=global instead.
employee#0.0.0 start
node ./bin/www
GET / - - ms - -
node:events:505
throw er; // Unhandled 'error' event
^
MongooseError: Query was already executed: Employee.find({})
at model.Query._wrappedThunk [as _find] (C:\Users\harsh\Desktop\Employee\node_modules\mongoose\lib\helpers\query\wrapThunk.js:21:19)
at C:\Users\harsh\Desktop\Employee\node_modules\kareem\index.js:426:25
at processTicksAndRejections (node:internal/process/task_queues:78:11)
Emitted 'error' event on Function instance at:
at C:\Users\harsh\Desktop\Employee\node_modules\mongoose\lib\model.js:4996:15
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
originalStack: 'Error\n' +
' at model.Query._wrappedThunk [as _find] (C:\Users\harsh\Desktop\Employee\node_modules\mongoose\lib\helpers\query\wrapThunk.js:25:28)\n' +
' at C:\Users\harsh\Desktop\Employee\node_modules\kareem\index.js:426:25\n' +
' at processTicksAndRejections (node:internal/process/task_queues:78:11)'
}
But if i use only employee.save() without function then the form data get posted and after
restarting the server again the data is showing in table but i want the data to be updated at
the same time so i used rendering again as mentioned in above code.

unable to change password using mongoose

I am using MongoDB, mongoose, ejs and NodeJS for my site. I have a update password function which is not working properly. I have checked again and again by login different things in console and there is no problem in getting data in req. So I guess my problem is in the controller. This is my controller:
module.exports.update_password = function (req, res) {
console.log(req.user);
Company.findOne({ username: req.user.username }, function (err, user) {
if (user.password == req.body.current_password) {
if (req.body.new_password == req.body.confirm_password) {
Company.findOneAndUpdate({ username: req.user.username }, { password: req.body.new_password }, { upsert: true }, function (err, doc) {
if (err) return res.send(500, { error: err });
req.flash('notify', 'Password changed!')
return res.redirect('/profile');
});
}
else req.flash('notify', 'New password does not match with confirm password');
}
else req.flash('notify', '!')
});
return res.redirect('/profile');
}
everytime updating my password I get this error:
node:events:355
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:329:5)
at ServerResponse.setHeader (node:_http_outgoing:573:11)
at ServerResponse.header (/home/krush/github/Project_Lightspeed/node_modules/express/lib/response.js:771:10)
at ServerResponse.location (/home/krush/github/Project_Lightspeed/node_modules/express/lib/response.js:888:15)
at ServerResponse.redirect (/home/krush/github/Project_Lightspeed/node_modules/express/lib/response.js:926:18)
at /home/krush/github/Project_Lightspeed/controllers/authentication_controller.js:45:32
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/model.js:4857:16
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/model.js:4857:16
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/helpers/promiseOrCallback.js:24:16
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/model.js:4880:21
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/query.js:4397:11
at /home/krush/github/Project_Lightspeed/node_modules/kareem/index.js:136:16
at processTicksAndRejections (node:internal/process/task_queues:76:11)
Emitted 'error' event on Function instance at:
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/model.js:4859:13
at /home/krush/github/Project_Lightspeed/node_modules/mongoose/lib/helpers/promiseOrCallback.js:24:16
[... lines matching original stack trace ...]
at processTicksAndRejections (node:internal/process/task_queues:76:11) {
code: 'ERR_HTTP_HEADERS_SENT'
}
[nodemon] app crashed - waiting for file changes before starting...
It seems that the problem is that the return res.redirect('/profile'); command is executed before your callback functions. Which is normal since this is how the event loop works.
Try to remove the return res.redirect('/profile'); line to see if the error goes away. Callbacks at node.js execute at a later stage of the event loop.
Generally I would recommend to refactor your code to use promises instead of callbacks since that causes the "callback hell" anti-pattern.
If you refactor your code to use promises, then you will be able to use .then or async await, which will help you write cleaner code and help you spot any error easily.

Mongoose CastError

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.

Node.js Mongoose PUT Failed

I am trying to PUT mongoose data using postman but it shows "TypeError: bear.save is not a function" in server console and crash the node app.
In this problem I am running two apps on different ports and db with the same code, normal http app can make all requests(POST,PUT,DEL,GET) success but another https app can't make PUT request, it can only make POST and GET successfully .
I can't understand why the same code on http app not showing error if it was code problem. Please help me.
REST API reference from - Here
.get(function(req, res) {
Bear.find( {ID: req.params.bear_id} , function(err, bear) {
if (err)
res.send(err);
res.jsonp(bear);
});
})
.put(function(req, res) {
Bear.find( {ID: req.params.bear_id}, function(err, bear) {
if (err)
res.send(err);
bear.Name = req.body.Name;
//res.json(bear) can send data up to this line
// save the bear (crash after following line)
bear.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Bear updated!' });
});
})
});
Error Log on console -
TypeError: bear.save is not a function
at Promise.<anonymous> (/var/www/vhosts/mydomain.com/nodeapp.js:130:18)
at Promise.<anonymous> (/var/www/vhosts/mydomain.com/node_modules/mpromise/lib/promise.js:162:8)
at emitOne (events.js:96:13)
at Promise.emit (events.js:188:7)
at Promise.emit (/var/www/vhosts/mydomain.com/node_modules/mpromise/lib/promise.js:79:38)
at Promise.fulfill (/var/www/vhosts/mydomain.com/node_modules/mpromise/lib/promise.js:92:20)
at /var/www/vhosts/mydomain.com/node_modules/mongoose/lib/query.js:1736:26
at model.Document.init (/var/www/vhosts/mydomain.com/node_modules/mongoose/lib/document.js:251:11)
at completeMany (/var/www/vhosts/mydomain.com/node_modules/mongoose/lib/query.js:1734:12)
at cb (/var/www/vhosts/mydomain.com/node_modules/mongoose/lib/query.js:1697:11)
You probably want to use findOne instead of find.

How to test a function that throws an error asynchronously, using tape?

I am attempting to test this module (receiver.js) for an error thrown:
var request = require('request')
module.exports = function(url){
request({
url: url,
method: 'POST'
}, function(error) {
if(error){
throw error
}
})
}
using this test (test.js):
var test = require('tape')
test('Receiver test', function(t){
var receiver = require('./receiver')
t.throws(function(){
receiver('http://localhost:9999') // dummy url
}, Error, 'Should throw error with invalid URL')
t.end()
})
but tape runs the assertion before the error is thrown, resulting in the following error message:
TAP version 13
# Receiver test
not ok 1 Should throw error with invalid URL
---
operator: throws
expected: |-
[Function: Error]
actual: |-
undefined
at: Test.<anonymous> (/path/to/tape-async-error-test/test.js:5:4)
...
/path/to/receiver.js:9
throw error
^
Error: connect ECONNREFUSED 127.0.0.1:9999
at Object.exports._errnoException (util.js:856:11)
at exports._exceptionWithHostPort (util.js:879:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1062:14)
Is there a way around this?
Generally, using tape, you have to ensure you call assert.end() after the async call has completed. Using promises (would require request-promise and returning the promise):
test('Receiver test', function(t){
// Tells tape to expec a single assertion
t.plan(1);
receiver('http://localhost:9999')
.then(() => {
t.fail('request should not succeed')
})
.catch(err => {
t.ok(err, 'Got expected error');
})
.finally({
t.end();
});
});
Using async/await:
test('Receiver test', async function(t) {
try {
await receiver('http://localhost:9999');
assert.fail('Should not get here');
} catch (err) {
assert.ok(err, 'Got expected error');
}
t.end();
});
The above example is mostly correct but here's a complete working example that compares async to synchronous side by side and also shows how to check for the error message in a manner similar to the tape examples given on tape's README.md.
test('ensure async function can be tested to throw', async function(t) {
// t.throw works synchronously
function normalThrower() {
throw(new Error('an artificial synchronous error'));
};
t.throws(function () { normalThrower() }, /artificial/, 'should be able to test that a normal function throws an artificial error');
// you have to do this for async functions, you can't just insert async into t.throws
async function asyncThrower() {
throw(new Error('an artificial asynchronous error'));
};
try {
await asyncThrower();
t.fail('async thrower did not throw');
} catch (e) {
t.match(e.message,/asynchronous/, 'asynchronous error was thrown');
};
});

Resources