[英]Mongoose - How can I throw more than one error in pre (save/update) middleware?
[英]How to throw an error from an async mongoose middleware post hook
从异步Mongoose中间件 发布挂钩中引发错误的正确方法是什么?
以下TypeScript代码使用mongoose的post init
事件来运行一些检查,这些检查在函数从mongoDb中检索文档时触发。 本postInit()
函数正在执行一些后台检查。 在某些情况下应该会失败,然后返回Promise.reject('Error!');
schema.post('init', function (this: Query<any>, doc: any) {
return instance.postInit(this, doc)
.catch( err => {
return err;
});
});
钩子工作正常。 即以下代码触发了钩子:
MyMongooseModel.findOne({ _id : doc.id}, (err, o : any) => {
console.log(o);
});
但是,如果postInit()
失败,则该错误不会传递回调用函数。 而是返回文档。
我正在寻找正确的方法将此错误传递给调用函数。 如果后台检查失败,则调用函数不应收回文档。
我尝试了多种方法来引发此错误。 例如, throw new Error('Error');
。 但是,这将导致UnhandledPromiseRejectionWarning
并仍返回文档。
在此post init hook方法中,您只会收到一个doc :
Document.prototype.init()
参数doc由mongo返回的“对象”文档初始化文档,而不使用设置方法或标记任何已修改的内容。
从mongodb返回文档后在内部调用。
猫鼬文档: Init HookDocumentation
为了触发错误,您需要完成或下一个方法:
发布中间件
挂钩方法及其所有前置中间件完成后,将执行后置中间件。 发布中间件不会直接接收流控制,例如, 不会将下一个或完成的回调传递给它。 post hooks是为这些方法注册传统事件侦听器的一种方法。
猫鼬文档: 后中间件
如果您只想知道呼叫中是否发生错误,请为此进行更改:
MyMongooseModel.findOne({ _id : doc.id}, (err, o : any) => {
if(err) {
throw new Error(err);
}
console.log(o);
});
如果要传播错误,则一个选项是使用预钩方法:
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');
});
错误处理示例: 错误处理
猫鼬维护者在这里。 不幸的是, init()
挂钩是同步的,并且我们还没有很好地记录下来。 我们打开了GitHub问题 ,并将尽快添加文档。 报告post('init')
的错误的唯一方法是throw
错误。
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!"
}
这是因为Mongoose假定init()
在内部是同步的 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.