【问题标题】:Using the docs but completely confused... mongoose Model#save使用文档但完全困惑...猫鼬模型#save
【发布时间】:2017-08-24 17:10:30
【问题描述】:

我正在尝试返回特定的状态代码,例如 409 冲突。我用过Model#save docs

编辑:我不是要解决这个错误,这是故意的。

根据文档,回调中有三个参数:err、product 和 numAffected。

编辑:我写错了这段代码,我编辑了。不管怎样,我从 Ryan 那里得到了很好的回答。

  app.post('/skill', (req, res) => {
    const skill = new Skill({some_duplicate_object});
    skill.save((err, product, numAffected) => {
        console.log("Error: ", err);

    });

不是我的 console.log,在 Mocha 测试 cli 中,我收到一个错误:

(node:19760) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 5): ValidationError: Path `name` is required.



通过玩弄运气,我做到了:这不在 mongoose 文档中,这是我写这篇文章的主要原因。

  app.post('/skill', (req, res) => {
    const skill = new Skill({});
    skill.save()
      .then((err, product, numAffected) => {
        console.log("Nothing displayed here");
    }, (err) => {
      console.log(err.errors);
    });

即使这不在文档中,它也会显示我想要的错误。作为一个真正尝试更多使用官方文档的人,我发现很难理解到底发生了什么。为什么这会起作用?如果它在文档中,这些信息会在哪里?

{ name: 
   { MongooseError: Path `name` is required.
       at ValidatorError (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/error/validator.js:24:11)
       at validate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:706:13)
       at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:752:11
       at Array.forEach (native)
       at SchemaString.SchemaType.doValidate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:712:19)
       at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/document.js:1408:9
       at _combinedTickCallback (internal/process/next_tick.js:73:7)
       at process._tickCallback (internal/process/next_tick.js:104:9)
     message: 'Path `name` is required.',
     name: 'ValidatorError',
     properties: 
      { type: 'required',
        message: 'Path `{PATH}` is required.',
        validator: [Function],
        path: 'name',
        value: undefined },
     kind: 'required',
     path: 'name',
     value: undefined,
     reason: undefined } }

额外信息:

  "devDependencies": {
    "chai": "^3.5.0",
    "mocha": "^2.4.5",
    "request": "^2.81.0",
    "supertest": "^3.0.0"
  },
  "dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "mongoose": "^4.9.2"
  }

【问题讨论】:

  • 您在 Mocha 中看到了错误,因为在 catch() 中没有错误。你需要skill.save().then(function(result){}).catch(function(err){})
  • 看起来skill 也设置了一些验证,我抱怨您没有传递PATH 值的错误。
  • 您已在架构中设置了所需的名称字段,因此当您尝试保存文档时出现验证错误,因为没有提供名称

标签: node.js express mongoose mocha.js chai


【解决方案1】:

你的问题是双重的,你得到的两个错误都在告诉你确切地出了什么问题。你的麻烦的根源是缺乏理解(而不是试图挑剔你)。这有点像你是电子产品的初学者,我告诉你管子偏向不正确,你说“我不明白”——好吧,你需要了解管子,因为我刚刚向你描述过确切你的电路的问题。

1.承诺错误 - UnhandledPromiseRejectionWarning: Unhandled promise rejection...。这再形容不过了。 Promise 要么 1) 解决,要么 2) 拒绝。如果您未能“处理”被拒绝的案例,您将收到错误消息。处理被拒绝的承诺可以通过以下两种方式之一发生:

// pass a 2nd function to `.then()`:
somePromise.then(function (result) {
  // promise was "resolved" successfully
}, function (err) {
  // Promise was "rejected"
});

// use `.catch()` - this is preferred in my opinion:
somePromise.then(function (result) {
  // promise was "resolved" successfully
}).catch(function (err) {
  // Promise was "rejected"
});

使用上述任何一种情况都意味着您正确“处理”了 Promise 拒绝。

2。数据库验证 - Path 'name' is required.。这实际上意味着您有一个名为“name”的必需路径,它是必需的(意思是,它必须有一个值)。所以看看你的代码就很明显了:

const skill = new Skill({});
skill.save() //-> results in error

通过在保存之前添加所有必需的数据来解决此问题:

const skill = new Skill({ name: "Jason" });
skill.save() //-> yay, no error

【讨论】:

  • 看起来我没有把它当作一个 Promise 对象。你说得对,我没看懂。所以我的第二个函数参数是 Promise 对象的“rejected”参数?与 .catch((err)=>{}) 本质上是一样的吗?
  • 是的,没错。我认为他们假设您知道如何正确使用 Promise,否则他们的示例将几乎翻倍。
  • Ryan,我第一个例子写错了,我修好了。我的担心来自 save() 方法没有错误。添加第二个函数参数时我只得到一个错误(现在我看到这是一个承诺对象,它们完全不同)。如果我知道我现在所知道的,我会以完全不同的方式问这个问题。
  • 不用担心 - 我并不想像“你什么都不知道,你这个白痴!” ;) Promise 可能会令人困惑。
【解决方案2】:

你没有处理承诺拒绝。

改变这个:

.then((err, product, numAffected) => {
    console.log("Error: ", err);
});

到这里:

.then((result) => {
    console.log('Result:', result);
}).catch((error) => {
    console.log('Error:', error);

当然,将回调中发生的内容更改为您需要的任何内容。

有关未处理拒绝的更多一般信息,请参阅此答案:

【讨论】:

    猜你喜欢
    • 2016-01-23
    • 2018-12-23
    • 2021-05-17
    • 1970-01-01
    • 2018-08-20
    • 2014-07-29
    • 2015-01-27
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多