2016-09-21 91 views
0

因此,我有一個節點服務器啓動並運行一個api端點,當通過郵遞員輸入重複的電子郵件時,端點不斷崩潰。如果發生非重複註冊,服務器將繼續運行而不會打嗝。但是,如果一個重複的電子郵件提交,我看到郵遞員重複的電子郵件錯誤:當重複註冊發生時,節點快遞服務器崩潰

{ 
    "code": 11000, 
    "index": 0, 
    "errmsg": "E11000 duplicate key error collection: register.users index: email_1 dup key: { : \"[email protected]\" }", 
    "op": { 
    "userRole": "isUser", 
    "password": "yudfjadjslkafdaljj343", 
    "zip": "94596", 
    "state": "CA", 
    "city": "Walnut Creek", 
    "address2": "", 
    "streetAddress": "1 fake address ", 
    "phoneNumber": "(925) 555-0644", 
    "email": "[email protected]", 
    "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... 

提前感謝您幫助解決這一問題。謝謝!

回答

1

您發送two反應,這就是爲什麼你收到此錯誤

我不認爲你需要使用next()回調,如果您要發送的save function響應,這將是fail or success

嘗試操作後返回你的反應是這樣

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

這絕對解決了這個問題。我選擇這個作爲最佳答案b/c在兩個地方似乎都需要return語句。謝謝! –

0

在您的模式中以及嘗試插入重複記錄時,您具有唯一性:true。它違反了模式驗證規則。您應該爲查詢使用異常處理並解析這些錯誤。你可以使用try-catch塊,如果你使用promise,那麼在每個查詢中使用catch塊。

發送有關重複保存記錄的響應。添加以下到你的路由器的ErrorHandler:

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

,並從響應的ErrorHandler返回它。

2

當發生錯誤時(即拋出異常),您正在發送兩個響應。您可以通過返回next()或在您撥打電話後返回來減輕此影響。

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

調用'next'是不是在這種情況下,真正有用的(也可能是有害的,因爲它可能會導致產生額外的404響應),如響應已經通過調用'res.send()'結束。 – robertklep

+0

好點,更新 –

相關問題