【问题标题】:Unhandled exceptions with async await异步等待未处理的异常
【发布时间】:2017-12-10 18:56:10
【问题描述】:

我正在尝试将我的旧回调样式函数转换为异步等待。但是我不明白如何捕获未处理的异常。

例如,假设我有一个函数

  apiCall(input, function(error, result) {
    if (error) {
      console.log(error);
    } else {
      console.log(result);
    }
  });

我转换为Promise

function test1(input) {
  return new Promise(function(resolve, reject) {
    apiCall(input, function(err, result) {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
}

那我就叫它

test1(4)
  .then(function(result) {
    console.log('Result: ' + result);
  })
  .catch(function(errorr) {
    console.log('My Error: ' + errorr);
  });

即使我尝试返回错误,有时这个函数也会崩溃。假设磁盘错误、JSON 解析错误等。一些我没有处理的错误。我只能用

来捕捉这些错误
process.on('uncaughtException', function(error) {
  console.log('uncaughtException' + error);
});

有没有办法让我用 async await 捕捉各种错误?

编辑:这是完整的 github repo 供您尝试

https://github.com/tosbaha/promise

运行 node testme.js 并查看它崩溃并且异常处理程序没有运行。

可能崩溃的文件是this 任何函数都可能崩溃,但我无法预见每一种错误。这就是为什么我正在寻找一种解决方案来捕获此文件中的错误。

如果您使用node testme.js 在我的仓库中运行代码,您将收到以下错误

        results[trackingId] = trackingArray.doesntExist.Something;
                                                        ^
TypeError: Cannot read property 'Something' of undefined

如您所见,catch 处理程序没有捕获错误。

【问题讨论】:

  • 可能在任何时候都只定义了rejectresolve。而不是使用if..else 使用reject(err || ''); resolve(result);
  • 如果 apiCall 返回错误,这是可行的。如果 apiCall 返回结果,这将再次起作用。但是,如果 apiCall 由于我没有在 apiCall 中处理的 Cannot read property 'Something' of undefined 而崩溃,那么除了 uncaughtException handler 之外我无法捕获此错误
  • 在这些情况下考虑使用try...catch
  • 堆栈跟踪说明了什么?你确定那是你的代码失败了吗?也许其他部分失败,process.on() 在进程死亡之前处理它?
  • 你应该链接到实际文件和代码行,例如this

标签: javascript node.js


【解决方案1】:

如果apiCall 可以在不调用回调的情况下崩溃(出现错误),我认为它会引发一些错误,可以使用try... catch 块在其外部处理(虽然我不确定,因为我不知道知道apiCall的内部代码)。

您可以尝试以下方法:

function test1(input) {
  return new Promise(function(resolve, reject) {
      try {
        apiCall(input, function(err, result) {
          if (err) {
            reject(err);
          } else {
            resolve(result);
          }
        });
      } catch (e) {
        // reject the errors not passed to the callback
        reject(e);
      }
  });
}

【讨论】:

  • 我发现在异步函数中捕获异常没有简单的方法。捕获此类异常的唯一方法是使用domain。我搜索了高低,即使域将被弃用,这是唯一的方法。
猜你喜欢
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多