mongodb dup 密钥错误 11000 使节点服务器崩溃
mongodb dup key error 11000 crashes node server
重复键 E11000 是预期的行为,但服务器崩溃不是。重复键错误来自我在电子邮件中的唯一索引。
控制器方法:
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 方法:
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;
};
UserSchema 中的电子邮件:
email: {
type: String,
unique: 'That email is already taken',
match: [/.+\@.+\..+/, 'Please use a valid e-mail address']
},
cli 输出:
λ 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
正如您在 cli 输出中看到的那样,我的 getErrorMessage 函数正在正确检索错误,我可以 console.log(message) 但此时节点服务器崩溃导致错误消息 res 未定义。
节点版本:0.12.4
MongoDB shell 版本:3.0.3
快递 4.12.4
猫鼬 4.0.5
Win 7 专业版 x64
我可以提供更多信息吗?
更新:
添加调用控制器方法的通行证策略
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);
}));
护照策略处理程序可以选择通过 req
(通过设置 passReqToCallback
),但不能通过 res
。因此,如果您需要策略处理程序中的响应对象,或从中调用的任何函数(如您的 users.saveOAuthUserProfile
),您需要使用 Express 将响应对象添加到请求对象的事实,您可以通过req.res
.
所以这个:
return res.redirect('/signup');
需要这样:
return req.res.redirect('/signup');
重复键 E11000 是预期的行为,但服务器崩溃不是。重复键错误来自我在电子邮件中的唯一索引。
控制器方法:
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 方法:
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;
};
UserSchema 中的电子邮件:
email: {
type: String,
unique: 'That email is already taken',
match: [/.+\@.+\..+/, 'Please use a valid e-mail address']
},
cli 输出:
λ 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
正如您在 cli 输出中看到的那样,我的 getErrorMessage 函数正在正确检索错误,我可以 console.log(message) 但此时节点服务器崩溃导致错误消息 res 未定义。
节点版本:0.12.4 MongoDB shell 版本:3.0.3 快递 4.12.4 猫鼬 4.0.5 Win 7 专业版 x64
我可以提供更多信息吗?
更新: 添加调用控制器方法的通行证策略
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);
}));
护照策略处理程序可以选择通过 req
(通过设置 passReqToCallback
),但不能通过 res
。因此,如果您需要策略处理程序中的响应对象,或从中调用的任何函数(如您的 users.saveOAuthUserProfile
),您需要使用 Express 将响应对象添加到请求对象的事实,您可以通过req.res
.
所以这个:
return res.redirect('/signup');
需要这样:
return req.res.redirect('/signup');