异步/等待错误处理



我正在尝试处理我的async方法抛出的自定义错误,但try catch块无法正常工作。

我认为我这样做的方式应该有效,但错误没有被捕获,程序通过在终端中显示它来终止。

这是它抛出错误的地方:

async setupTap(tap) {
const model = this.connection.model('Tap', TapSchema);
await model.findOneAndUpdate({ id: tap.id }, tap, (err, result) => {
let error = null;
if (!result) {
throw new Error('Tap doesn't exists', 404);
}
return result;
});
}

然后,错误处理代码:

async setupTapHandler(request, h) {
const tapData = {
id: request.params.id,
clientId: request.payload.clientId,
beerId: request.payload.beerId,
kegId: request.payload.kegId,
};
try {
await this.kegeratorApi.setupTap(tapData);
} catch (e) {
if (e.code === 404) return h.response().code(404);
}
return h.response().code(204);
}

有人可以帮助我吗?

我还研究了其他主题:

正确的尝试...使用 Async/Await 捕获语法

如何在异步/等待情况下正确实现错误处理

只有在等待承诺时,才能使用await成功等待异步操作。 假设你正在使用猫鼬,我不太了解猫鼬,但如果你给它一个回调,model.findOneAndUpdate()似乎不会返回承诺。 相反,它会执行并将结果放在回调中。

此外,从这样的回调中执行throw只会扔到数据库(调用回调的代码)中,对您没有任何好处。 要让throw做出被拒绝的承诺,您需要从异步函数的顶层抛出,或者从.then().catch()处理程序内部或承诺执行器函数内部抛出。 这就是抛出承诺被拒绝的地方。

这里的关键是您希望对数据库使用 promise 接口,而不是回调接口。 如果你不传递回调,那么它会返回一个查询,你可以使用它.exec()来获得一个承诺,然后你可以与await一起使用。

此外,您没有生成将.code属性设置为 404 的错误对象。 这不是 Error 对象构造函数支持的属性,因此如果需要该属性,则必须手动设置它。

我会建议这个:

async setupTap(tap) {
const model = this.connection.model('Tap', TapSchema);
let result = await model.findOneAndUpdate({ id: tap.id }, tap).exec();
if (!result) {
let err = new Error('Tap doesn't exists');
err.code = 404;
throw err;
}
return result;
}

或者,这里只有一个异步操作,使用await真的没有多大好处。 你可以这样做:

setupTap(tap) {
const model = this.connection.model('Tap', TapSchema);
return model.findOneAndUpdate({ id: tap.id }, tap).exec().then(result => {
if (!result) {
let err = new Error('Tap doesn't exists');
err.code = 404;
throw err;
}
return result;
});
}

函数 findOneAndUpdate 返回一个承诺,因此不需要回调。如果需要回调并且您无法更新到较新版本,则可以将调用包装在承诺中(在To use a callback api as promise you can do:下)

然后你想在错误时设置代码,你不能用构造函数这样做。

async setupTap(tap) {
const model = this.connection.model('Tap', TapSchema);
const result =   await model.findOneAndUpdate({ id: tap.id }, tap);
if (!result) {
const e = new Error('Tap doesn't exists');
e.code = 404;
throw(e);
}
return result;
}
async setupTapHandler(request, h) {
const tapData = {
id: request.params.id,
clientId: request.payload.clientId,
beerId: request.payload.beerId,
kegId: request.payload.kegId,
};
try {
await this.kegeratorApi.setupTap(tapData);
} catch (e) {
if (e.code === 404) return h.response().code(404);
}
return h.response().code(204);
}

最新更新