我试图理解为什么上载函数中的catch块无法捕获createReleaseVersion函数中request(.....)行之后引发的异常。 nodejs脚本崩溃,并且未处理异常。控制台中仅显示异常错误。
在以下代码中,我希望先打印“先了解您然后再整理”,但这不会发生。
如果我用return return(...相同的对象)替换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');
答案 0 :(得分:2)
好吧,我们来看一个简单的例子:
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
对象,以获得更好的堆栈跟踪。