Node.js 为什么在这个NodeJS异步函数中没有捕捉到错误?
我试图理解为什么upload函数中的catch块没有捕获createReleaseVersion函数中请求(…)行之后抛出的异常。 nodejs脚本崩溃,异常未处理。控制台中只显示异常的错误 在下面的代码中,我希望打印“got you”然后打印“after”,但这并没有发生 如果我将throw替换为return-reject(…相同的对象),那么我将获得所需的输出。Node.js 为什么在这个NodeJS异步函数中没有捕捉到错误?,node.js,error-handling,promise,async-await,Node.js,Error Handling,Promise,Async Await,我试图理解为什么upload函数中的catch块没有捕获createReleaseVersion函数中请求(…)行之后抛出的异常。 nodejs脚本崩溃,异常未处理。控制台中只显示异常的错误 在下面的代码中,我希望打印“got you”然后打印“after”,但这并没有发生 如果我将throw替换为return-reject(…相同的对象),那么我将获得所需的输出。 我先印上“抓住你”然后印上“之后” function createReleaseVersion(releaseVersion) {
我先印上“抓住你”然后印上“之后”
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
)预订了稍后调用的回调
当回调最终被调用时,承诺构造函数已经执行完毕,错误被抛出到当前上下文(setTimeout/request)中
promise构造函数同步捕获错误的原因是它基本上是这样做的:
try {
executor(resolve, reject); // your code
} catch (e) {
reject(e);
}
因为在您的情况下,函数不会同步执行——它无法了解异常的上下文。这在将来可能会随着分区而改变,但可能不会
如果要在promisified函数中标记错误,可以调用第二个参数(reject
)和reject(newerror(…)
)
我强烈建议您使用util.promisify
而不是手动将API转换为承诺,以避免此类问题:)
我也建议您只拒绝使用代码>错误< /Cord>对象以获得更好的堆栈跟踪。
,让我们采取一个更简单的例子:
new Promise((resolve, reject) => {
setTimeout(() => { throw new Error(); });
});
这会使整个过程崩溃。原因是setTimeout
(或者在您的情况下是request
)预订了稍后调用的回调
当回调最终被调用时,承诺构造函数已经执行完毕,错误被抛出到当前上下文(setTimeout/request)中
promise构造函数同步捕获错误的原因是它基本上是这样做的:
try {
executor(resolve, reject); // your code
} catch (e) {
reject(e);
}
因为在您的情况下,函数不会同步执行——它无法了解异常的上下文。这在将来可能会随着分区而改变,但可能不会
如果要在promisified函数中标记错误,可以调用第二个参数(reject
)和reject(newerror(…)
)
我强烈建议您使用util.promisify
而不是手动将API转换为承诺,以避免此类问题:)
我还建议您仅拒绝带有
错误的对象,以获得更好的堆栈跟踪。谢谢您的回答。关于您编写的“如果您想在promisified函数中标记错误-您可以调用第二个参数(reject)和reject(new error(…)”,还有一个问题。你能提供更多的细节吗?我怎样才能做到这一点。您的意思是将请求调用包装在resolve中吗?当然:new Promise((resolve,reject)=>setTimeout(()=>reject(new Error()))
将创建一个被拒绝的承诺-这不是抛出新错误,它在那里不起作用。谢谢你的回答。还有一个关于你所写内容的问题“如果你想在promisified函数中标记一个错误-你可以调用第二个参数(拒绝)和拒绝(新错误(…)“。您能提供更多详细信息吗?我该如何实现该方法。您的意思是将请求调用封装在resolve中吗?当然:new Promise((resolve,reject)=>setTimeout(()=>reject(new Error())
将创建一个被拒绝的承诺-而不是抛出新错误
,这在那里不起作用。相关问题和答案:(认为它有用-但不是真正的副本)相关问题和答案:(认为它有用-但不是真正的副本)