Mongoose首次创建Post成功第二次失败,Promise无reject却触发catch?
问题原因分析
- 核心触发原因:你在
create方法内部重复注册了同名Mongoose模型。Mongoose不允许覆盖已经编译完成的模型,第一次执行mongoose.model('Post', postSchema)时会完成Post模型的注册,第二次调用create方法时再次执行该注册逻辑,会直接抛出同步错误。而Promise执行器函数内部的同步错误会被自动捕获,将Promise状态置为rejected,因此哪怕你没有手动调用reject(),也会触发外层的catch回调。 - 额外存在的逻辑问题:
- 验证失败分支未调用
reject(),会导致验证不通过时Promise一直处于pending状态,无法触发后续回调。 - 验证逻辑存在参数匹配错误:你实例化
Post时传入的第一个参数是req.body.text(字符串类型),但validate方法中判断的是this.data.text,对字符串取text属性永远返回undefined,你的非空验证逻辑实际永远不会生效。 save操作未做错误处理,数据库写入失败时无法捕获异常。
- 验证失败分支未调用
修复方案
将Schema定义和模型注册逻辑移到模块顶层,仅执行一次,同时修复上述逻辑问题,修改后代码如下:
// Post.js file const mongoose = require('mongoose') // 模型定义移到顶层,全局仅注册一次 const postSchema = new mongoose.Schema({ body: String, author: String, }) const PostModel = mongoose.model('Post', postSchema) let Post = function(data, user) { this.data = data this.username = user this.errors = [] } Post.prototype.validate = function() { // 修复验证逻辑,直接判断传入的文本内容 if (this.data == "") { this.errors.push("Cannot be left blank") } } Post.prototype.create = function() { return new Promise((resolve, reject) => { this.validate() if (!this.errors.length) { const post = new PostModel({ body: this.data, author: this.username }) // 增加save操作的错误处理 post.save((err) => { if (err) return reject(err) resolve() }) } else { // 验证失败主动抛出错误 reject(this.errors) } }) } module.exports = Post
内容的提问来源于stack exchange,提问作者Justin Christopher Domingo
相关产品推荐
相关产品推荐

