2015-07-04 1 views
0

Повторяющийся ключ E11000 - ожидаемое поведение, но сбой сервера - нет. Дублированная ключевая ошибка исходит из моего уникального индекса по электронной почте.mongodb dup ошибка ключа 11000 аварийный сервер узла

Метод

Контроллер:

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'] 
}, 

кли:

λ 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 (сообщение), но на этом этапе происходит сбой сервера узла, в результате чего появляется сообщение об ошибке, что res не определено. версия

узел: 0.12.4 MongoDB версия оболочки: 3.0.3 выразить 4.12.4 мангуст 4.0.5 Win 7 Pro x64

Все больше информации я могу предоставить?

UPDATE: Добавление стратегии паспорта, который вызывает метод контроллера

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

вы можете разместить код для метода контроллера? – hassansin

+0

@hassansin Я думал, что только часть сохранения будет актуальна, но будет обновлена, чтобы добавить весь метод. Спасибо – isimmons

+1

так же, как я думал: я не вижу никаких «res» в области метода – hassansin

ответ

1

обработчики стратегии Passport имеют возможность получить переданный req (путем установки passReqToCallback), но не res. Поэтому, если вам нужен объект ответа в обработчике стратегии или любые вызываемые из него функции (например, ваш users.saveOAuthUserProfile), вам нужно использовать тот факт, что Express добавляет объект ответа к объекту запроса, к которому вы можете получить доступ через req.res.

Так что:

return res.redirect('/signup'); 

должно быть так:

return req.res.redirect('/signup');