Atlante Avila Atlante Avila - 2 months ago 24
Node.js Question

Node express server crashes when duplicate registration happens

so I have a node server up and running with an api endpoint that keeps crashing when a duplicate email is entered via postman. If a non-duplicate registration takes place, the server keeps running with no hiccups. But if a duplicate email is submitted, I do see the duplicate email error on postman:

{
"code": 11000,
"index": 0,
"errmsg": "E11000 duplicate key error collection: register.users index: email_1 dup key: { : \"atlanteavila@gmail.com\" }",
"op": {
"userRole": "isUser",
"password": "yudfjadjslkafdaljj343",
"zip": "94596",
"state": "CA",
"city": "Walnut Creek",
"address2": "",
"streetAddress": "1 fake address ",
"phoneNumber": "(925) 555-0644",
"email": "fake@email.com",
"lastName": "Last",
"firstName": "Person",
"_id": "57e2b2e49f0de63201914616",
"__v": 0
}
}


Here's the api route:

var express = require('express');
var app = express();
var router = express.Router();
var User = require('../models/user');

module.exports = function (app) {

router.route('/users')

.get( function (req, res) {
res.json({ message: 'welcome!!' });
})

.post(function (req, res) {
var rb = req.body;
var user = new User();
user.firstName = rb.firstName;
user.lastName = rb.lastName;
user.email = rb.email;
user.phoneNumber = rb.phoneNumber;
user.streetAddress = rb.streetAddress;
user.address2 = rb.address2;
user.city = rb.city;
user.state = rb.state;
user.zip = rb.zip
user.password = rb.password;
user.userRole = rb.userRole;


user.save( function(err) {
if (err) {
res.send(err);
next();
};
res.json({ message: 'UserCreated!' });
});
});

app.use('/api', router);

}


and the mongoose schema:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true,
index: true,
unique: true
},
phoneNumber: {
type: String,
required: true
},
streetAddress: {
type: String,
required: true
},
address2: String,
city: {
type: String,
required: true
},
state: {
type: String,
required: true
},
zip: {
type: String,
required: true
},
password: {
type: String,
required: true
},
userRole: {
type: String,
required: true
}
});

module.exports = mongoose.model('User', UserSchema);


Finally the error on the terminal:

[nodemon] restarting due to changes...
[nodemon] starting `node server/server.js`
Up and running on port 3000
events.js:160
throw er; // Unhandled 'error' event
^

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/Users/atlanteavila/Documents/myapps/register/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/Users/atlanteavila/Documents/myapps/register/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/Users/atlanteavila/Documents/myapps/register/node_modules/express/lib/response.js:250:15)
at /Users/atlanteavila/Documents/myapps/register/server/routes/signUp.js:34:11
at /Users/atlanteavila/Documents/myapps/register/node_modules/mongoose/lib/model.js:3336:16
at /Users/atlanteavila/Documents/myapps/register/node_modules/mongoose/lib/document.js:1932:15
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
[nodemon] app crashed - waiting for file changes before starting...


Thanks in advance for any assistance in figuring this one out. Thanks!

Answer

You are sending two responses, that's why you are getting this error

I don't think you need to use next() callback if you are sending the response in save function which will be fail or success.

Try to return your response after manipulation like this

user.save( function(err) {
      if (err) {
       return res.send(err);
      };
      return res.json({ message: 'UserCreated!' });
    });