该代码非常简单。 ks3 is a library其他人开发的。它具有启动功能来下载文件。它使用async.auto
来做到这一点。
我用bluebird Promise.promisifyAll
包裹它
let ks3p = Promise.promisifyAll(ks3) //ks3 has a start function
try {
await ks3p.startAsync(param)
} catch (err) {
//failed to catch fs.renameSync
}
但是有时候我会得到错误
fs.js:115
throw err;
^
Error: ENOENT: no such file or directory, rename ... -> ...
at Object.renameSync (fs.js:591:3)
那么,为什么try catch块无法捕获该块呢?
我进一步检查了the start() implementation。它使用async下载文件,但是没有什么特别的。
async.auto({
step_1 : ...
step_2 : ...
},
function(err, results) {
if (err) {
if (cb) {
cb(err, results)
} else {
fs.unlinkSync(configFile);
throw err;
}
} else {
fs.unlinkSync(configFile);
fs.renameSync(downFileName, filePath);
if (cb) {
cb(err, {msg:'success',path:filePath}, null);
}
}
})
------更新-------
我用Promise.promisifyAll包装的部分原因是我不知道如何捕获该错误。我的原始代码是这样的
ks3.download.start(param, (err, result) => {
//But how do I catch the exception start throw asynchronously ?
if (err) {
// error handling
} else {
log(`finished download ${file}`)
}
done()
})
------更新2 -------
进一步研究问题之后(答案很有帮助),我发现我修改了ks3代码,或者必须使用domain来捕获异常。我知道domain is deprecated。但是对于这个特定的问题,我发现它是适当的b/c,我确切地知道是什么引起了该问题,并且目前我也没有解决该问题(b/c,这是我无法控制的npm模块)。
最佳答案
有关其他上下文,请参见try/catch block not catching async/await error,但是要回答有关如何在和 promise 的版本中捕获错误的问题,则必须在引发错误时了解调用堆栈。
你有过
ks3.download.start(param, (err, result) => {
//But how do I catch the exception start throw asynchronously ?
if (err) {
// error handling
} else {
log(`finished download ${file}`)
}
done()
})
您应该将其视为:
var cb = (err, result) => {
//But how do I catch the exception start throw asynchronously ?
if (err) {
// error handling
} else {
log(`finished download ${file}`)
}
done()
});
ks3.download.start(param, cb);
并且是
start
本身引发了异常(在调用或安排回调之前),因此您需要将该调用包装在try-catch中:var cb = (err, result) => {
//But how do I catch the exception start throw asynchronously ?
if (err) {
// error handling
} else {
log(`finished download ${file}`)
}
done()
});
try {
ks3.download.start(param, cb);
} catch (ex) {
// here.
}
不过,我对
async.auto
的异常处理有点怀疑,而且我担心它可能正在异步运行某些东西而没有捕获错误。特别是,它看起来并不像期望callback
函数曾经抛出过(请参见https://github.com/caolan/async/blob/master/lib/auto.js),但是如果fs
方法失败,https://github.com/ks3sdk/ks3-nodejs-sdk/blob/master/lib/api/download.js确实会抛出,就像您看到的那样。因此,除了a)修复
ks3
或b)可能找到一种猴子修补fs
认为永远不会抛出的ks3
版本之外,您无能为力的事情。在这两个中,(a)对我来说听起来容易得多,我认为它应该看起来像这样:async.auto({
// ...
},
function(err, results) {
if (cb) {
if (err) {
cb(err);
return;
}
try {
fs.unlinkSync(configFile);
fs.renameSync(downFileName, filePath);
} catch (ex) {
cb(ex);
return;
}
cb(err, {msg:'success', path:filePath}, null);
} else {
// really, i wouldn't even bother fix this case and just make cb required.
}
})
最重要的是,我假设这是一个错误,即如果有错误并且有回调,则
ks3
代码不会删除配置文件。