[英]Mongoose returning document even though an error was thrown
我有一個 Express.js 路由,可以通過用戶名和密碼從我的 MongoDB 數據庫中檢索用戶。 我的目標是從請求正文中獲取用戶名和密碼,通過用戶名找到用戶,然后驗證密碼是否匹配。 如果密碼匹配,我想返回用戶對象和 200 狀態代碼,如果密碼不匹配,我想返回帶有錯誤消息的 404。
目前我的路線正在運行,但用戶總是被返回,即使密碼不匹配。 我正在檢查它們是否匹配並拋出錯誤,但似乎並沒有像我預期的那樣拋出。 理想情況下,如果密碼在我的服務調用中不匹配,我想拋出一個錯誤,並在我的路由中捕獲它以返回正確的狀態代碼。
我試圖在我的路線中捕獲錯誤並從服務返回一個被拒絕的承諾,但用戶仍然被返回。 我的預感是在返回記錄后運行findOne
接受的回調?
我在控制台中收到一個 UnhandledPromiseRejectionWarning,它對應於如果密碼不匹配我拋出錯誤的行:
app_1 | GET /user 200 221 - 4.297 ms
app_1 | (node:257) UnhandledPromiseRejectionWarning: Error: Password does not match
app_1 | at /usr/src/app/services/userService.ts:17:37
app_1 | at Generator.next (<anonymous>)
app_1 | at fulfilled (/usr/src/app/services/userService.ts:5:58)
服務器.ts
注:我重命名find
對進口findUser
通過find as findUser
app.get('/user', authenticateToken, async (req: Request, res: Response): Promise<void> => {
const user = await findUser(req.body.username, req.body.password);
if (!user) {
res.status(404).send();
return;
}
res.status(200).send({ user });
});
用戶服務.ts
const find = (username: string, password: string) => {
return User.findOne({ username }, async (err: Error, user: any) => {
if (err) throw err;
const passwordMatches = await user.validatePassword(password);
if (!passwordMatches) throw Error("Password does not match")
});
}
user.ts(用戶貓鼬模型)
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';
interface User {
username: string;
password: string;
isModified: (string: any) => boolean;
}
const SALT_WORK_FACTOR = 10;
const userSchema = new mongoose.Schema({
username: { type: String, required: true, index: { unique: true } },
password: {
type: String,
unique: false,
required: true
}
},
{ timestamps: true }
);
userSchema.pre('save', function(next) {
const user = this as unknown as User;
if (!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, (err: any, salt: any) => {
if (err) return next(err);
bcrypt.hash(user.password, salt, function(err: any, hash: any) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
userSchema.methods.validatePassword = function (pass: string) {
return bcrypt.compare(pass, this.password);
};
const User = mongoose.model('User', userSchema);
export { User };
在我的userService
我改變了用findOne
查詢的方式來解決這個問題。 我從閱讀模型上的貓鼬 findOne 是否返回承諾中得到這個想法?
const find = (username: string, password: string) => {
return User.findOne({ username }).exec().then((user: any) => {
const passwordMatches = user.validatePassword(password);
if (!passwordMatches) throw Error("Password does not match")
return user;
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.