node.js - 为什么在此NodeJS异步函数中未捕获错误?

标签 node.js error-handling promise async-await

我试图了解为什么上载函数中的catch块不能捕获createReleaseVersion函数中request(...)行之后引发的异常。
nodejs脚本崩溃,并且未处理异常。控制台中仅显示异常错误。

在下面的代码中,我希望先打印“先得到您”,再打印“之后”,但这不会发生。

如果我用返回拒绝(...相同的对象)替换throw,那么我将得到所需的输出。
我先打印“得到你”,然后打印“之后”

function createReleaseVersion(releaseVersion) {
    var options = {
        uri: 'https://someurl',
        method: 'POST',
        json: {'version': releaseVersion}
    };

    return new Promise(function(resolve, reject) {
        request(options, function (error, response, body) {
            throw {
                error: error,
                response: response,
                body: body
            };
            console.log(body);
            if (error) {
                throw {
                    error: error,
                    response: response,
                    body: body
                };
            } else {
                resolve();
            }
        });
    });
}

async function upload(releaseVersion) {
    try {
        await createReleaseVersion(releaseVersion);
    } catch (error) {
        console.log('got you');
    }
    console.log('after');
}

upload('ddd');

最佳答案

好吧,让我们来看一个简单的例子:

new Promise((resolve, reject) => {
  setTimeout(() => { throw new Error(); });
});

这使进程崩溃。原因是setTimeout(或您的情况下的request)预订了一个回调,以便稍后调用。

当回调最终被调用时-promise构造函数已经完成执行,并且错误被抛出到当前上下文(setTimeout/request的上下文)中。

promise构造函数同步捕获错误的原因是因为它基本上是这样做的:
try {
   executor(resolve, reject); // your code
} catch (e) {
   reject(e);
}

因为在您的情况下,该函数无法同步执行-它无法了解异常的上下文。将来在区域中这可能会改变,但可能不会改变。

如果要在函数内部标记错误,则可以调用第二个参数(reject)和reject(new Error(...))

我热烈建议您使用util.promisify而不是将API手动转换为Promise,以避免出现此类问题:)

我还建议您仅拒绝使用Error对象以获得更好的堆栈跟踪。

关于node.js - 为什么在此NodeJS异步函数中未捕获错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51154577/

相关文章:

javascript - 无法理解 MDN 文档中 Promise.prototype.then() 的注释

html - Node.js Webm 直播服务器 : issues with <video> tag

node.js - 安装 yomen 时疑难解答。谁能帮我解决这个问题..!

wordpress - 在WordPress中进行调试

javascript - IndexedDB - 如何读取对象存储中的最大 ID

javascript - Deftjs promise 完成()不工作

node.js - 我可以使用带有扩展参数的dynamicHelpers (expressjs)吗?

javascript - React native - 如何过滤数组异步(async/await)

batch-file - 批处理命令和错误处理

rest - API应该为已更新但未更改的值返回什么响应代码?