繁体   English   中英

异步/等待错误处理

[英]Async/Await error handling

我正在尝试处理我的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捕获语法

如何在async / await情况下正确实现错误处理

如果您正在等待承诺,则只能使用await成功等待异步操作。 假设你正在使用mongoose,我不太了解model.findOneAndUpdate() ,但是如果你传递一个回调,看起来model.findOneAndUpdate()不会返回一个promise。 相反,它执行并将结果放入回调中。

此外,做一个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返回一个promise,因此不需要回调。 如果需要回调并且您无法更新到更新版本,那么可以在promise中包含调用 (在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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM