ランダムユーザーが複数のアカウントを作成するのを防ぐためにトークンを使用する登録システムを実装しているときに問題が発生しました。
コードは最後まで実行され、応答は期待どおりに機能しますが、後で警告が表示されます:UnhandledPromiseRejectionWarning:エラー[ERR_HTTP_HEADERS_SENT]:ヘッダーがクライアントに送信された後でヘッダーを設定できません
問題は44行目で発生すると言っています。これは、mongooseのsaveメソッドのcatchステートメントです。
newRegistrationToken.save()
.then(newRegistrationToken => res.status(200).json(newRegistrationToken))
.catch(err => res.status(500).json(err));
私は解決策を探していましたが、常に、catchステートメントが欠落していて、この警告が表示されるという答えがありました。ただし、私のコードでは、不足しているcatchステートメントは表示されないため、ここで少し迷っています。
ルート全体は次のとおりです。
router.post('/create', (req, res) => {
const { errors, isValid } = validateRegistrationToken(req.body);
if(!isValid) return res.status(400).json(errors);
// Searching for an active token associated with the e-mail address given
console.log("search for active token");
ModelRegistrationToken.findOne({
email: req.body.email,
expiresAt: { $gte: Date.now() }
}).then(user => {
// if user found
if(user){
// check if the user is already registered
console.log("search for registered user");
ModelUser.findOne({email: user.email}).then((registered) => {
if(registered)
return res.status(400).json({email: 'There\'s a user already registered with the e-mail address given'});
return res.status(400).json({email: 'The address given already has an active registration token'});
}).catch(err => console.log(err));
}
// Otherwise create a new token
const newRegistrationToken = new ModelRegistrationToken({
email: req.body.email,
expiresAt: new Date(Date.now() + Number.parseInt(config.REG_TOKEN_EXPIRATION_PERIOD) * 24 * 60 * 60 * 1000)
});
console.log("save token");
newRegistrationToken.save()
.then(newRegistrationToken => res.status(200).json(newRegistrationToken))
.catch(err => res.status(500).json(err));
}).catch(err => res.status(500).json(err));
});
私にはこれを理解できないようですので、これについてあなたの助けをお願いします。
あなたが持っている:
if (user) {
// do stuff and call res.json
}
// do other stuff and call res.json
user
存在する場合、res.json
2回呼び出されます。if (user)
ブロックの下部に戻ってみてください:
if (user) {
// check if the user is already registered
console.log("search for registered user");
ModelUser.findOne({
// ...
}).catch(err => console.log(err));
return; // <---------------------------------
}
// Otherwise create a new token
const newRegistrationToken = new ModelRegistrationToken({
email: req.body.email,
expiresAt: new Date(Date.now() + Number.parseInt(config.REG_TOKEN_EXPIRATION_PERIOD) * 24 * 60 * 60 * 1000)
});
// ...
内部でfindOne
エラーが発生した場合はステータス500を送信することをお勧めします。そうしないと、応答がハングします。
}).catch(err => console.log(err));
のようなものに
}).catch(err => res.status(500).json(err));
他の場所でやっているように。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加