如何处理 Node.js 中的异步错误

How to handle asynchronous error in Node.js

除了 Bluebird 的 Promise.try 函数之外,还有其他替代方法吗?因为我正在使用 async/await 对添加蓝鸟依赖不感兴趣。

有没有更好的方法在Node.JS

中捕获asynchronous error
await Promise.try(async function() {
    // Some code with async operations like readline
    await this.nextCall(batchData, true);
}).catch(async function(err) {
    // My error handling
});

Node.js 10.x 中是否有内置函数?

更新 :

有没有更好的方法在Node.JS

中捕获asynchronous error
try {
    let interfaceVal = lineReader.createInterface({
        input: fs.createReadStream(filePath)
    });
    interfaceVal.on('line', async (line) => {
        throw new Error('My custom Error');
    });
    // some sync operations
} catch(e) {
    // This catch wont get called with custom error
    console.log(e);
}

有捕获此类异步错误的想法吗?

在 nodeJs 中,如果您使用 async/await,您可以使用普通的 try catch 块,它会捕获您的错误(并且它适用于异步调用)

try {
   await this.nextCall(batchData, true);
}
catch(exc) {
 // handle error
}

这个函数定义需要声明为async

您不需要在异步函数中明确指定 catch 子句,因为它使用自然的错误语义。这里你的函数 operation_A 抛出一个错误,因为 operation_B rejected.

const operation_B = () => {
    return new Promise((resolve,reject) => {
        window.setTimeout(() => {
            //resolve("RESOLVE: all your base are belong to us");
            reject("REJECT: all your base are belong to us");
        },2000);
    });
};

const operation_A = async () => {
   const B = await operation_B();
   return B.toUpperCase();
};

operation_A().then(console.log).catch(console.error);

没有理由用 Promise.try 包装 async 函数。 Promise.try 的目的是类似地处理同步错误和拒绝:

Start the chain of promises with Promise.try. Any synchronous exceptions will be turned into rejections on the returned promise.

这已经用 async 完成了,因为它总是 returns 一个承诺。

这可以在顶层与 async IIFE 一起使用:

(async function() {
    await this.nextCall(batchData, true);
})().catch(console.error);

或者如果 async 是嵌套的,它可以省略,可以在父 async 函数中使用 try..catch 处理拒绝,正如另一个答案所解释的那样。


在这种情况下,只能在 async 函数内捕获错误:

    interfaceVal.on('line', async (line) => {
      try {
        throw new Error('My custom Error');
      } catch (err) {
        console.error(err);
      }
    });

使用非承诺 API(节点流)不允许使用承诺进行错误处理。流回调忽略被拒绝的承诺,并且不允许将错误传播到流外。

回调只有在预期被调用时才能转换为承诺 onceline 不是这种情况。在这种情况下可以使用异步迭代器,this one of its use cases.

可以使用 p-event 将事件发射器转换为异步迭代器,并在 async 函数内使用 for await of 进行迭代:

try {
    let interfaceVal = lineReader.createInterface({
        input: fs.createReadStream(filePath)
    });

    const asyncIterator = pEvent.iterator(interfaceVal, 'line', {
      resolutionEvents: ['close']
    });

    for await (const event of asyncIterator) {
        console.log('line', event);
        // throw new Error('My custom Error');
    }
} catch(e) {
    console.log(e);
}

Promise.tryits way for specification. Here is the polyfill:

if (typeof Promise !== 'function') {
    throw new TypeError('A global Promise is required');
}

if (typeof Promise.try !== 'function') {
    Promise.try = {
        try(func) {
            if (typeof this !== 'function') {
                throw new TypeError('Receiver must be a constructor');
            }
            return new this(function (resolve) {
                resolve(func());
            });
        }
    }.try;
}

此 polyfill 支持 promise 子类化和其他功能。这可以安全地填充 Node.js.