2012-09-24 3 views
10

を表現し、私はマングースを使用してサインアップフォームを作成したと11000(ユーザーが既に、そのユーザ名で存在する場合には、私はerr.codeを得る3はどのようにマングースに重複したキーから回復+

その可能表現するために重複キー)。既存のユーザーをどのように扱うべきですか?

これは私が今やっているものです....しかし、私は、エラーコードを確認するかわからないが最善の方法です:

user.save(function(err){ 
    if (err) { 
     console.log(err); 
     console.log(err.code); 

     //duplicate key 
     if (err.code == 11000) { 
     req.flash('error', 'User already exists'); 
     res.redirect('/signup'); 
     return; 
     } 
    } 

    res.locals.user = user; 
    req.session.user = user; 
    //res.locals.session = req.session; 
    res.redirect('/'); 
    }); 

は、これを行うのより良い方法はありますか?

+0

はかなりきれいに見えます。特に、あなたにはそれについてかなり気にしないことは何ですか? – JohnnyHK

+0

ちょうど私が最初にユーザをチェックするのではなく、dbにエラーを投げさせるという事実。 – chovy

+0

それは、あなたの状況において、別の解決策を「より良い方法」にするかどうかによって異なります。難しくないようにしようとはしませんが、これが機能的に正確で、パフォーマンスが適切でメンテナンス可能な場合は...? – JohnnyHK

答えて

3

私はこれをまだ試していないが、これは、私は思考がエラーを発生しないようになるんだものです:

//look for existing user first 
user.findOne({ username: req.body.username }, function(err, user) { 
    if (err) throw err; 

    //existing user found, stop registration 
    if (user) { 
     res.flash('error', "That user already exists"); 
     res.redirect('/signup'); 
     return; 
    } 

    //create new user 
    var user = new User({ username: req.body.username }); 

    user.save(function(err){ 
    if (err) throw err; 
     res.flash('info', "Your account has been created"); 
     res.redirect('/account'); 
    }); 
}); 
+0

'.count()'を使うこともできます。これはやや簡潔で覚えやすいものですが、必要に応じて返されたデータを使用することはできません。 –

+0

Ps、私はmongooseが 'Model.saveUnique({username:req.body.username}、function(err){...});)のようなものを持っているべきだと思います; –

+0

重複するキーエラーを処理する方が実際に安全ですこれは、 'user.findOne()'がコレクションを読み込み、 'user.save()'が実行されるときの間に別の要求がユーザを作成した可能性があるためです。つまり、あなたのAPIが5xxエラーを投げる可能性のある競合状態があります。ユーザーがまだ存在しないことを期待しているフォームでは、それを保存してからDuplicateKeyエラーを処理しようとするとコードが少なくなり(user.findOne()は必要ありません)、この競合状態は回避されます。エンティティがすでに存在することを期待する場合は、最初にエンティティをロードしようとする方が自然かもしれません。 – binki

13

はこれを試してみてください:

user.save(function(err){ 
    if (err && err.code !== 11000) { 
    console.log(err); 
    console.log(err.code); 
    res.send('Another error showed up'); 
    return; 
    } 

    //duplicate key 
    if (err && err.code === 11000) { 
    req.flash('error', 'User already exists'); 
    res.redirect('/signup'); 
    return; 
    } 

    res.locals.user = user; 
    req.session.user = user; 
    //res.locals.session = req.session; 
    res.redirect('/'); 
}); 

あなたがこの方法をログにエラーを埋めることはありません。

+0

それは私が持っていたものではありませんか?違いは何ですか?エラーは関係なくログに表示されます...これがどのように異なっているかはわかりません。 – chovy

+0

申し訳ありません@chovy、少し私の答えを変更しました。 - 最初の条件は、エラーが「重複キー」エラーではなく、「別のエラーが表示されました」というエラーがクライアントに返された場合に発生します。 - エラーが「重複キー」エラーの場合は、2番目の条件が発生します。 - エラーがなければ、指示に従ってスクリプトが実行されます。 – red

+0

私は感謝します - ありがとう。私はまだクエリがエラーを投げたので、エラーがログに記録されていると思います。 user.findOne(..、function(err、user)){if(!user)new User(); user.save()}); – chovy

関連する問題