Can't set headers after they are sent node - node.js

I have the following route for the password reset form, the form has a password and password confirmation field.
router.post('/users/reset/:token', (req, res, next) => {
if(req.body.password === req.body['password-confirm']) {
req.flash('error', 'Passwords do not match!');
res.redirect('/users/forgot');
}
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: { $gt: Date.now() }
}, function(err, user) {
if(!user) {
req.flash('error', ' Password reset is invalid or has expired');
res.redirect(302, '/login');
}
const setPassword = promisify(user.setPassword, user);
setPassword(req.body.password);
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
const updatedUser = user.save();
user.save((saveError, updatedUser) => {
// Check if saveError is present here and handle appropriately
req.login(updatedUser, loginError => {
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
res.redirect('/dashboard' + req.user);
})
});
});
});
When I fill out the form I get the following error
Fri Jan 26 2018 11:28:55 GMT+0000 (GMT): GET /users/reset/6e2574bfa532e0d13af7fae61114308f9a683767
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Fri, 26 Jan 2018 11:28:55 GMT") }, resetPasswordToken: '6e2574bfa532e0d13af7fae61114308f
9a683767' }, { fields: {} })
Fri Jan 26 2018 11:28:55 GMT+0000 (GMT): GET /favicon.ico
Fri Jan 26 2018 11:29:02 GMT+0000 (GMT): POST /users/reset/6e2574bfa532e0d13af7fae61114308f9a683767
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Fri, 26 Jan 2018 11:29:02 GMT") }, resetPasswordToken: '6e2574bfa532e0d13af7fae61114308f
9a683767' }, { fields: {} })
Mongoose: users.update({ _id: ObjectId("5a5c6740b9e210087e098fd6") }, { '$unset': { resetPasswordExpires: 1, resetPasswordToken: 1 } })
Mongoose: users.update({ _id: ObjectId("5a5c6740b9e210087e098fd6") }, { '$unset': { resetPasswordExpires: 1, resetPasswordToken: 1 } })
(node:1451) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'apply' of undefined
at /Users/benbagley/Code/poetry-out-loud/node_modules/es6-promisify/dist/promisify.js:75:41
at new Promise (<anonymous>)
at /Users/benbagley/Code/poetry-out-loud/node_modules/es6-promisify/dist/promisify.js:54:20
at /Users/benbagley/Code/poetry-out-loud/routes/users.js:321:5
at model.Query.<anonymous> (/Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/model.js:4056:16)
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:273:21
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:131:16
at process._tickCallback (internal/process/next_tick.js:150:11)
(node:1451) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a c
atch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1451) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminat
e the Node.js process with a non-zero exit code.
Fri Jan 26 2018 11:29:02 GMT+0000 (GMT): GET /users/forgot
events.js:136
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at validateHeader (_http_outgoing.js:503:11)
at ServerResponse.setHeader (_http_outgoing.js:510:3)
at ServerResponse.header (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:767:10)
at ServerResponse.location (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:884:15)
at ServerResponse.redirect (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/response.js:922:18)
at req.login.loginError (/Users/benbagley/Code/poetry-out-loud/routes/users.js:332:13)
at /Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/http/request.js:51:48
at /Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/sessionmanager.js:16:14
at pass (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/authenticator.js:297:14)
at Authenticator.serializeUser (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/authenticator.js:299:5)
at SessionManager.logIn (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/sessionmanager.js:14:8)
at IncomingMessage.req.login.req.logIn (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/http/request.js:50:33)
at user.save (/Users/benbagley/Code/poetry-out-loud/routes/users.js:330:11)
at /Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/model.js:4056:16
at /Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/services/model/applyHooks.js:170:20
at process._tickCallback (internal/process/next_tick.js:150:11)
I'm still new to node so any refactoring tips, or fixes for this would be most appreciated, been stuck on this issue for a few days, not sure what I'm doing wrong.
Thank you.

First thing is that this error occur when node sent response of API call more than one time. Secondly, it is best practice to use return when sending response for example return res.json(<OBJECT>);
In your code you are checking the password like
req.body.password === req.body['password-confirm']
it should be like
req.body.password !== req.body['password-confirm']
that may the case that causing node to sent multiple response

You are sending response to client multiple time, that's why facing Cannot set headers after they are sent to the client error.
In your case, your are not returning (exiting) from the function execution when you should have. E.g. when password doesn't match, you are trying to redirect user to /users/forgot, but you are not returning the function there. Hence, code below if condition executes and try to send response back again.
Solution:
router.post('/users/reset/:token', (req, res, next) => {
if // some condition {
// some code
return res.redirect('/users/forgot');
}
User.findOne({
// some code
}, function(err, user) {
if(!user) {
// some code
return res.redirect(302, '/login');
}
// some code
user.save((saveError, updatedUser) => {
req.login(updatedUser, loginError => {
// some code
return res.redirect('/dashboard' + req.user);
})
});
});
});

Related

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.

chai and mocha showing test successful after error

I am using chai and mocha to test my REST API developed in NodeJS with typescript. I have written my test cases with mockgoose library to mock mongo db. When I run the first test case it successfully adds some data in database, but when I run the second and third test case it first shows Cannot set headers after they are sent to the client and later shows that the test is passed. I am not getting this workflow of execution how is it happening. Could anyone please explain.
My test case file looks like this :
process.env.NODE_ENV = 'TEST';
import { expect } from 'chai';
import request from 'supertest';
import app from '../app';
import * as mongodb from '../mongo/connection';
describe('Testing the API', () => {
before((done) => {
mongodb.connectMock()
.then(() => done())
.catch((err:any) => done(err))
})
it('OK, adding new employee', (done) => {
request(app).put('/add')
.send(<some JSON data>)
.then(res => {
...some matcher
done();
})
.catch(err => done(err));
})
it('OK, getting all employees', (done) => {
request(app).get('/all')
.then(res => {
...some matcher
done();
})
.catch(err => {
done(err)
});
})
it('OK, getting employee by ID', (done) => {
request(app)
.get(`/create/${id}`)
.then(res => {
...some matcher
done();
})
.catch(err => done(err));
})
})
and the controller file that produces the error is :
import { Request, Response } from 'express';
import Employee from '../models/Employee'
import { v4 as uuidv4 } from 'uuid';
export let allEmployee = (req: Request, res: Response) => {
Employee.find({})
.then(allEmployee => {
console.log('Getting all employee');
if(allEmployee.length > 0)
res.status(200).json(allEmployee);
console.log('Empty set of employees, please create');
res.status(404).json({ error: 'No employee found, please create', employee: allEmployee });
})
.catch((err:any) => {
console.log(err)
res.status(400).json({ error: err }); ****** I GET THE ERROR HERE ******
})
}
export let getEmployeeById = (req: Request, res: Response) => {
const employeeId: string = req.params.id;
Employee.find({ employeeId: employeeId })
.then(employee => {
console.log(`Getting employee with employee ID: ${employeeId}`);
if(employee.length > 0)
res.status(200).json(employee);
console.log(`No employee with employee ID: ${employeeId} found`);
res.status(404).json({ error: 'No employee found', employee: employee });
})
.catch(err => {
res.status(400).json({ error: err }); ****** I GET THE ERROR HERE ******
})
}
export let addEmployee = (req: Request, res: Response) => {
let employee = new Employee(<Some employee data in JSON>)
employee.save()
.then(employeeSaved => {
res.status(201).json({ message: 'New employee created!', employee: employeeSaved });
})
.catch(err => {
res.status(400).json({error:err});
})
}
The first test case that adds the employee to database works perfectly fine but when it does for second and third test case it shows error first and then successfully passes the test case.
It looks like :
Mock MongoDB Connected
✓ OK, adding new employee (69ms)
Getting all employees
Empty set of employees, please create
(node:16761) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:771:10
)
at ServerResponse.send (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:267:15)
at /Users/abc/Downloads/some/git-test/some/Docker_Solution/src/controllers/employeeController.ts:16:33
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:16761) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch bl
ock, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rej
ections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 9)
(node:16761) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
✓ OK, getting all employees
Getting employee with employee ID: 2b1e419e-57a7-4785-a3d7-96a1c786676b
No employee with employee ID: 2b1e419e-57a7-4785-a3d7-96a1c786676b found
(node:16761) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:771:10)
at ServerResponse.send (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/Users/abc/Downloads/some/git-test/some/Docker_Solution/node_modules/express/lib/response.js:267:15)
at /Users/abc/Downloads/some/git-test/some/Docker_Solution/src/controllers/employeeController.ts:31:33
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:16761) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 10)
✓ OK, getting employee by ID
3 passing (1s)
Your problem seems to be your if conditions for res.status(200) or res.status(400) in both of your routes you have an issue with.
if(employee.length > 0)
res.status(200).json(employee);
console.log(`No employee with employee ID: ${employeeId} found`);
res.status(404).json({ error: 'No employee found', employee: employee });
should be and if(){} else{} because you are trying to send/alter the response again along with the 200 you already send
if(employee.length > 0) {
res.status(200).json(employee);
} else {
console.log(`No employee with employee ID: ${employeeId} found`);
res.status(404).json({ error: 'No employee found', employee: employee });
}

Keep getting the "ConfigError: Missing region in config" error in Node.js no matter what I do

I keep getting the "UnhandledPromiseRejectionWarning: ConfigError: Missing region in config" when trying to make requests to APIs I have set up in Node.js.
I'm new to DynamoDB and after setting up most of my boilerplate code I'm using Postman to test my routes. However I keep getting the same error each time I make a post request. I've checked some solutions on existing threads, namely: Configuring region in Node.js AWS SDK but cannot get it to work.
I am currently developing the app locally and checked the database where the items are being added.
My setup is as follows:
// user_controller.js
const uuid = require('uuid');
const sanitizer = require('validator');
const bcrypt = require('bcryptjs-then');
const AWS = require('aws-sdk');
const config = require('../config/config');
const { signToken, userByEmail, userById } = require('../Helpers/Users');
const isDev = true
Then in my code block I have the following:
// user_controller.js
(...)
if (isDev) {
AWS.config.update(config.aws_local_config);
} else {
AWS.config.update(config.aws_remote_config);
}
const DB = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: config.aws_table_name,
Item: {
userId: await uuid.v1(),
firstName: sanitizer.trim(firstName),
lastName: sanitizer.trim(lastName),
email: sanitizer.normalizeEmail(sanitizer.trim(email)),
password: await bcrypt.hash(password, 8),
level: 'standard',
createdAt: new Date().getTime(),
updatedAt: new Date().getTime(),
},
}
return userByEmail(params.Item.email) // Does the email already exist?
.then(user => { if (user) throw new Error('User with that email exists') })
.then(() => DB.put(params).promise()) // Add the data to the DB
.then(() => userById(params.Item.id)) // Get user data from DB
.then(user => (err, data) => {
console.log("AFTER USER CREATED")
if (err) {
res.send({
success: false,
message: 'Error: Server error'
});
} else {
console.log('data', data);
res.send({
statusCode: 201,
message: 'Success - you are now registered',
data: { token: signToken(params.Item.id), ...user },
});
}
})
(...)
Finally I am importing the config from separate file:
// config.js
module.exports = {
aws_table_name: 'usersTable',
aws_local_config: {
region: 'local',
endpoint: 'http://localhost:8000'
},
aws_remote_config: {}
}
In have already configured the aws-sdk:
AWS Access Key ID [****************foo]:
AWS Secret Access Key [****************bar]:
Default region name [local]:
Default output format [json]:
Here is the output I keep getting:
(node:4568) UnhandledPromiseRejectionWarning: ConfigError: Missing region in config
at Request.VALIDATE_REGION (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:92:45)
at Request.callListeners (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at callNextListener (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
at /Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:86:9
at finish (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:350:7)
at /Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:368:9
at SharedIniFileCredentials.get (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/credentials.js:127:7)
at getAsyncCredentials (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:362:24)
at Config.getCredentials (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/config.js:382:9)
at Request.VALIDATE_CREDENTIALS (/Users/BANGBIZ/Programming/techstars/capexmove/SmartLegalContract/node_modules/aws-sdk/lib/event_listeners.js:81:26)
(node:4568) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:4568) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Like I said, I've tried a lot of variations on this but to no avail. Would love some help, thanks.
I dont know if this helps, but I used none instead of local for the region and it seemed to work for me
AWS.config.update({ region: 'none' })

mongodb update is throwing a critical error

When I try to update a user using a web form, it runs a app.post on express. The object user is correct, but sometimes it throws a error in node console
app.post('/register/update', jsonParser, (request, response) => {
let user = request.body.user;
let users = mongoUtil.users();
console.log(user);
users.update({email: user.email}, user, (err, res) => {
if(err) {
response.sendStatus(400);
}
response.sendStatus(201);
});
});
In node console:
{ _id: '578246ec9eb0587a5d67b8c9',
email: 'test#test.com',
zipcode: '1231-123',
companyName: 'test',
tradeName: 'test',
contactName: 'Test',
tel: '(14) 1232-1231',
password: 'test',
passwordConfirm: 'test',
adress: 'test',
adressComplement: 'test',
adressNumber: '123' }
/home/ec2-user/ ... /mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/home/ec2-user/ ... /node_modules/express/lib/response.js:719:10)
at ServerResponse.contentType (/home/ec2-user/ ... /node_modules/express/lib/response.js:552:15)
at ServerResponse.sendStatus (/home/ec2-user/ .. /node_modules/express/lib/response.js:340:8)
at users.update (/home/ec2-user/menuWebApp/server/app.js:94:14)
at handleCallback (/home/ec2-user/ ... /node_modules/mongodb/lib/utils.js:96:12)
at /home/ec2-user/ ... /node_modules/mongodb/lib/collection.js:1008:42
at commandCallback (/home/ec2-user/ ... /node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:1194:9)
at Callbacks.emit (/home/ec2-user/ ... /node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:119:3)
at Connection.messageHandler (/home/ec2-user/ ... /node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:358:23)
I'm probably dealing with a callback problem, but I don't have idea how to solve it D:
The error is not coming from the update statement itself its coming from your callback function.
Specifically these lines of code.
if(err) {
response.sendStatus(400);
}
response.sendStatus(201);
What you are doing is if there is an error send the status 400, then send the status 201. The problem is once you send a response with your headers to the requestor you can't try and set the headers again.
So your code should change to:
if(err) {
response.sendStatus(400);
}else{
response.sendStatus(201);
}
So if an error is generated you will send a 400 response otherwise you will send a 201 response instead of trying to send a 400 response and then a 201 response immediately after.

mongodb dup key error 11000 crashes node server

Duplicate key E11000 is the expected behavior but crashing the server is not. The duplicate key error comes from my unique index on email.
controller method:
exports.saveOAuthUserProfile = function(req, profile, done) {
User.findOne({
provider: profile.provider,
providerId: profile.providerId
}, function(err, user) {
if (err) {
return done(err);
} else {
if (!user) {
var possibleUsername = profile.username || ((profile.email) ? profile.email.split('#')[0] : '');
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
profile.username = availableUsername;
user = new User(profile);
user.save(function(err) {
if (err) {
var message = getErrorMessage(err);
console.log(message);
//req.flash('error', message);
return res.redirect('/signup');
}
return done(err, user);
});
});
} else {
return done(err, user);
}
}
});
};
getErrorMessage method:
var getErrorMessage = function(err) {
var message = '';
// If an internal MongoDB error occurs get the error message
if (err.code) {
switch (err.code) {
// If a unique index error occurs set the message error
case 11000:
message = 'Duplicate Key';
break;
case 11001:
message = 'Username already exists';
break;
// If a general error occurs set the message error
default:
message = 'Something went wrong';
}
} else {
// Grab the first error message from a list of possible errors
for (var errName in err.errors) {
if (err.errors[errName].message) message = err.errors[errName].message;
}
}
return message;
};
email in UserSchema:
email: {
type: String,
unique: 'That email is already taken',
match: [/.+\#.+\..+/, 'Please use a valid e-mail address']
},
cli output:
λ node server
Server running at http://localhost:3000/
GET / 200 26.879 ms - 1347
GET /lib/angular-route/angular-route.min.js 200 12.790 ms - 4408
GET /lib/angular-resource/angular-resource.min.js 200 13.863 ms - 3598
GET /modules/example/example.client.module.js 200 14.557 ms - 30
GET /modules/example/controllers/example.client.controller.js 200 12.595 ms - 240
GET /modules/example/config/example.client.routes.js 200 12.024 ms - 547
GET /lib/angular/angular.min.js 200 77.183 ms - 145234
GET /modules/users/users.client.module.js 200 24.306 ms - 28
GET /modules/users/services/authentication.client.service.js 200 25.467 ms - 168
GET /application.js 200 23.834 ms - 536
GET /modules/articles/articles.client.module.js 200 27.471 ms - 31
GET /modules/articles/services/articles.client.service.js 200 28.066 ms - 234
GET /modules/example/views/example.client.view.html 200 1.968 ms - 83
GET /lib/angular/angular.min.js.map 304 10.579 ms - -
GET /lib/angular-route/angular-route.min.js.map 304 17.932 ms - -
GET /lib/angular-resource/angular-resource.min.js.map 304 31.510 ms - -
GET /signin 200 5.881 ms - 606
GET /oauth/google 302 2.573 ms - 0
Duplicate Key
C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:108
if (this.ended && !this.hasRejectListeners()) throw reason;
^
ReferenceError: res is not defined
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\app\controllers\users.server.controller.js:107:22)
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:174:48)
at EventEmitter.emit (events.js:107:17)
at Promise.safeEmit (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:81:21)
at Promise.reject (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:109:15)
at Promise.error (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\promise.js:94:15)
at Promise.resolve (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\promise.js:112:24)
at C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\document.js:1578:39
at handleError (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:40:22)
at next_ (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:75:26)
at EventEmitter.fnWrapper (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:171:15)
at EventEmitter.<anonymous> (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:174:48)
at EventEmitter.emit (events.js:107:17)
at Promise.safeEmit (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:81:21)
at Promise.reject (C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\node_modules\mpromise\lib\promise.js:109:15)
at C:\Users\lotus\Desktop\mastering_mean\application\node_modules\mongoose\lib\model.js:263:20
As you can see in the cli output my getErrorMessage function is correctly retrieving the error and I can console.log(message) but at this point node server crashes resulting in the error message that res is not defined.
node version: 0.12.4
MongoDB shell version: 3.0.3
express 4.12.4
mongoose 4.0.5
Win 7 Pro x64
Any more information I can provide?
UPDATE:
Adding the passport strategy that calls the controller method
module.exports = function() {
passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.google.callbackURL,
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {
var providerData = profile._json;
providerData.accessToken = accessToken;
providerData.refreshToken = refreshToken;
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
fullName: profile.displayName,
email: profile.emails[0].value,
username: profile.emails[0].value.replace(/#.*$/,""),
provider: 'google',
providerId: profile.id,
providerData: providerData
};
users.saveOAuthUserProfile(req, providerUserProfile, done);
}));
Passport strategy handlers have an option to get passed req (by setting passReqToCallback), but not res. So if you need the response object in the strategy handler, or any functions called from it (like your users.saveOAuthUserProfile), you need to use the fact that Express adds the response object to the request object, which you can access through req.res.
So this:
return res.redirect('/signup');
Needs to be this:
return req.res.redirect('/signup');

Resources