Javascript 如何从异步mongoose中间件post钩子抛出错误

Javascript 如何从异步mongoose中间件post钩子抛出错误,javascript,node.js,mongodb,typescript,mongoose,Javascript,Node.js,Mongodb,Typescript,Mongoose,从异步post钩子抛出错误的正确方法是什么 代码示例 下面的TypeScript代码使用mongoose的postinit事件运行一些检查,每当函数从mongoDb检索文档时都会触发这些检查。本例中的postInit()函数正在执行一些背景检查。它应该在某些情况下失败,然后返回一个Promise.reject('Error!') 但是,如果postInit()失败,则不会将错误传递回调用函数。而是返回文档 预期行为 我正在寻找将此错误传递给调用函数的正确方法。如果背景检查失败,调用函数将无法取回

从异步post钩子抛出错误的正确方法是什么

代码示例 下面的TypeScript代码使用mongoose的post
init
事件运行一些检查,每当函数从mongoDb检索文档时都会触发这些检查。本例中的
postInit()
函数正在执行一些背景检查。它应该在某些情况下失败,然后返回一个
Promise.reject('Error!')

但是,如果
postInit()
失败,则不会将错误传递回调用函数。而是返回文档

预期行为 我正在寻找将此错误传递给调用函数的正确方法。如果背景检查失败,调用函数将无法取回文档


我尝试了不同的方法来提出这个错误。例如,
抛出新错误(“错误”)。但是,这会导致出现
未处理的PromiserEjectionWarning
,并且仍然返回文档。

在这个post init hook方法中,您只会收到文档

Document.prototype.init()

返回的参数文档«对象»文档 mongo在没有设置符或标记任何内容的情况下初始化文档 修改

从mongodb返回文档后在内部调用

猫鼬文件:

对于触发错误,您需要“完成”或“下一步”方法:

后中间件

post中间件在hooked方法及其所有 预中间件已经完成。post中间件不直接接收 流控制,例如,无下一步或完成回调传递给它。邮递 钩子是为这些应用程序注册传统事件侦听器的一种方法 方法

猫鼬文件:

如果您只想知道您的通话中是否发生了错误,请更改以下内容:

MyMongooseModel.findOne({ _id : doc.id}, (err, o : any) => {
      if(err) {
        throw new Error(err);
      }

      console.log(o);
    });
如果要传播错误,一个选项是使用prehook方法:

schema.pre('save', function(next) {
  const err = new Error('something went wrong');
  // If you call `next()` with an argument, that argument is assumed to be
  // an error.
  next(err);
});

schema.pre('save', function() {
  // You can also return a promise that rejects
  return new Promise((resolve, reject) => {
    reject(new Error('something went wrong'));
  });
});

schema.pre('save', function() {
  // You can also throw a synchronous error
  throw new Error('something went wrong');
});

schema.pre('save', async function() {
  await Promise.resolve();
  // You can also throw an error in an `async` function
  throw new Error('something went wrong');
});

错误处理示例:

这里是Mongoose维护者。不幸的是,
init()。我们开设了一个网站,并将尽快在上面添加文档。在
post('init')
中报告错误的唯一方法是抛出它

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);

const GITHUB_ISSUE = `init`;
const connectionString = `mongodb://localhost:27017/${ GITHUB_ISSUE }`;
const { Schema } = mongoose;

run().then(() => console.log('done')).catch(error => console.error(error.stack));

async function run() {
  await mongoose.connect(connectionString);
  await mongoose.connection.dropDatabase();

  const schema = new mongoose.Schema({
    name: String
  });
  schema.post('init', () => { throw new Error('Oops!'); });

  const M = mongoose.model('Test', schema);

  await M.create({ name: 'foo' });

  await M.findOne(); // Throws "Oops!"
}
这是因为猫鼬假设

schema.pre('save', function(next) {
  const err = new Error('something went wrong');
  // If you call `next()` with an argument, that argument is assumed to be
  // an error.
  next(err);
});

schema.pre('save', function() {
  // You can also return a promise that rejects
  return new Promise((resolve, reject) => {
    reject(new Error('something went wrong'));
  });
});

schema.pre('save', function() {
  // You can also throw a synchronous error
  throw new Error('something went wrong');
});

schema.pre('save', async function() {
  await Promise.resolve();
  // You can also throw an error in an `async` function
  throw new Error('something went wrong');
});
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);

const GITHUB_ISSUE = `init`;
const connectionString = `mongodb://localhost:27017/${ GITHUB_ISSUE }`;
const { Schema } = mongoose;

run().then(() => console.log('done')).catch(error => console.error(error.stack));

async function run() {
  await mongoose.connect(connectionString);
  await mongoose.connection.dropDatabase();

  const schema = new mongoose.Schema({
    name: String
  });
  schema.post('init', () => { throw new Error('Oops!'); });

  const M = mongoose.model('Test', schema);

  await M.create({ name: 'foo' });

  await M.findOne(); // Throws "Oops!"
}