我试图了解为什么上载函数中的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/