【问题标题】:Mongoose invalidate in pre validate hook does not throw error预验证钩子中的猫鼬无效不会引发错误
【发布时间】:2018-10-26 02:34:27
【问题描述】:

我的用户模型中有以下预验证钩子:

UserSchema.pre<IUser>('validate', async function (next: NextFunction): Promise<void> {
    if (!this.isModified('password')) {
        return next()
    }
    if (this.password.length < 8) {
        this.invalidate(
            'password',
            'Invalid password ...',
            ''
        )
        console.log(this.password)
    }
    this.password = await bcrypt.hash(this.password, 12)
})

架构是:

const UserSchema: mongoose.Schema = new mongoose.Schema({
    login: {
        required: true,
        type: String,
        unique: 'Le nom d\'utilisateur `{VALUE}` est déjà utilisé'
    },
    mail: {
        required: true,
        type: String,
        unique: 'Le mail `{VALUE}` est déjà utilisé'
    },
    password: { required: true, type: String, /*select: false*/ },
    // In test env auto validate users
    isVerified: { type: Boolean, default: config.env !== 'test' ? false : true },
    profilPic: { type: mongoose.Schema.Types.ObjectId, ref: 'Image' },
}, { timestamps: true })

但是在做的时候

try {
   await User.create({ login: 'user2', mail: 'user1@mail.com', password: '123' })
} catch (error) {
   console.log(error)
}

我有日志123,这表明代码进入了 pre hook 中的第二个if,但由于日志在this.invalidate 之后,我不明白为什么没有抛出错误。

我在其他一些模型中成功使用了相同的钩子,操作更复杂,没有错误。

我真的不明白为什么这个不起作用

【问题讨论】:

    标签: javascript node.js mongoose async-await mongoose-schema


    【解决方案1】:

    这种行为的背景是Document.prototype.invalidate() 没有抛出错误——它返回错误。为了停止当前中间件链的执行,您需要调用 next 并将此错误传递给它:

    if (this.password.length < 8) {
        const validationError = this.invalidate(
            'password',
            'Invalid password ...',
            ''
        );
        next(validationError);
        console.log(this.password); // Won't run
    }
    

    throw它:

    if (this.password.length < 8) {
        const validationError = this.invalidate(
            'password',
            'Invalid password ...',
            ''
        );
        throw validationError;
        console.log(this.password); // Won't run
    }
    

    【讨论】:

    • 我在另一个模型中使用了完全相同的功能,没有明确的return 也没有throw,但这可能在我这边
    • Document.prototype.invalidate() 的工作方式是将错误添加到文档实例的错误映射中并返回。在失效后立即运行Document.prototype.validate() 将传递一个带有errors 字段的对象和一些元数据作为validate() 回调的参数。您可以在docs with an example 中查看。也许你没有注意到invalidate() 没有抛出而是返回错误,因为没有更多的东西可以执行。
    • this.invalidate()返回的值尝试console.log,你会看到
    • 对不起,昨天有点累,没看到我的另一个模型中有return next()。您的两个解决方案都有效,非常感谢您
    【解决方案2】:

    Mongoose middleware documentation 未将创建列为受支持的操作。你试过保存吗?

    【讨论】:

    • 我可能遗漏了一些东西,但查看mongoosejs.com/docs/models.html create 显然是受支持的猫鼬操作。
    • Create 绝对是受支持的操作...只是在中间件支持的操作列表中没有提到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2012-08-08
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 2014-04-24
    相关资源
    最近更新 更多