发生重复注册时,节点快车服务器崩溃

Node express server crashes when duplicate registration happens

本文关键字:节点 服务器 崩溃 注册      更新时间:2023-09-26

所以我有一个节点服务器启动并运行一个api端点,当通过邮递员输入重复的电子邮件时,它会崩溃。如果发生了非重复的注册,服务器将继续运行,不会出现任何问题。但是,如果提交了重复的电子邮件,我确实会在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
  }
}

下面是api路由:

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);
}

和猫鼬模式:

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);

最后终端上的错误:

[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...

提前感谢你在解决这个问题上的任何帮助。谢谢!

你正在发送two响应,这就是为什么你得到这个错误

我不认为你需要使用next()回调,如果你发送的响应在save function将是fail or success

尝试在这样的操作后返回您的响应

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

当出现错误(抛出异常)时,您正在发送两个响应。您可以通过返回next()或在调用它之后返回来缓解此问题。

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

当您尝试插入重复记录时,您的模式中有unique: true。它违反了模式验证规则。您应该对查询使用异常处理并解析这些错误。你可以使用try-catch块,如果你使用promise,那么每个查询都使用catch块。

发送关于重复保存记录的响应。在你的router errorhandler中添加如下代码:

if (err instanceof Error && err.name === "MongoError" && err.driver) {
        if (err.code == 11000) { // unique index conflict
            return ['Resource document already exists.'];
        }
    }