Node.js 最佳实践异常处理 - Async/Await 之后

Node.js Best Practice Exception Handling - After Async/Await

他们已经是关于这个话题的问题了

Node.js Best Practice Exception Handling

这是旧的,答案非常过时,domains 从那以后甚至被弃用了。

现在在 post Async/Await Node.js 场景中,我们不应该类似地考虑同步和异步情况,并在同步函数中抛出异常并在异步函数中拒绝承诺,而不是返回一个Error 前者的实例。

let divideSync = function(x,y) {
    // if error condition?
    if ( y === 0 ) {
        // "throw" the error 
        throw new Error("Can't divide by zero exception")
    }
    else {
        // no error occured, continue on
        return x/y
    }
}

模拟异步除法运算

let divideAsync = function(x, y) {

  return new Promise(function(resolve, reject) {

    setTimeout(function() {
      // if error condition?
      if (y === 0) {
        // "throw" the error safely by rejecting the promise
        reject (new Error("Can't divide by zero exception"));
      } else {
        // no error occured, continue on
        resolve(x / y)
      }
    }, 1000);
  })

};

因此可以统一处理同步和异步异常

let main = async function () {
    try {
        //const resultSync = divideSync(4,0);
        const resultAsync = await divideAsync(4,0);
    }
    catch(ex) {
        console.log(ex.message);
    }

}

The answers from Node.js Best Practice Exception Handling are old and very much outdated

没那么多。 This answer, with the list from this well-maintained blog post,非常新。
The offical node.js guide 总是一本好书,一般方法没有太大变化。

那么发生了什么变化?

  • 域已损坏并已弃用。好吧,那是旧闻了。
  • 典型的 "node-style callbacks" 及其错误优先参数仅触发一次,不应再使用。这种简单的顺序异步编码风格及其所有问题已被 promises 和 async/await 取代。 (注意:事件发射器等是不同的情况[​​=52=])
  • process.on('uncaughtException')
  • 补充
  • 如果使用得当,promises 也会捕获程序员的错误。对于无聊的顺序异步代码,它们可以代替域。

那么这对通用代码意味着什么?

Shouldn't we consider sync and async cases similarly and throw exceptions in sync functions and rejecting promises in async functions instead of returning an Error instance?

是的,没错。你应该用 Errors 拒绝你的承诺(或者 throw 他们来自 async functions)。

请注意,您很少需要亲自给 reject 打电话。有了承诺,您应该能够 throw 在您的代码中。如果你不能,你可能没有正确使用它们 - 程序员的错误也不会在那里被发现。

此代码的黄金法则是:切勿使用非承诺回调的回调。 "Promise callbacks" 指的是 new Promisethencatch 参数,也可能是您的库的一些自定义方法(例如 finally)。这是上面的示例代码有问题的地方。写对了,应该是

async function divideAsync(x, y) {
    await new Promise(resolve =>
        setTimeout(resolve, 1000) // don't even pass a function expression
    );
    if (y === 0) {
        throw new Error("Can't divide by zero exception");
    } else {
        return x / y;
    }
}