在搜索SO后,我找不到这个问题的答案。我看到的所有问题,错误仍然被捕获。我遇到了逆问题。无论我如何重构以下代码,我仍然无法捕获错误。
我希望我只是忽略了某些事情或做错了事情。
process.on("uncaughtException", uncaughtExceptionListener)
start().catch(console.error)
async function start() {
try {
await queue.connect()
} catch (err) {
return console.error('Some Error:', err.message)
}
}
// queue.connect in class
async function connect() {
try {
// The next line is where the error originates
await client.connect()
return console.log('Never makes it here')
} catch (err) {
// Never makes it here either
return console.error('[client] Connection failed!')
}
}
输出:
node:internal/process/promises:391
triggerUncaughtException(err, true /* fromPromise */);
^
Error: connect ECONNREFUSED 127.0.0.1:6090
我用多种不同的方式尽可能简单地重写了
connect()
:
function connect() {
const p2 = new Promise((resolve, reject) => {
client.connect().then(resolve).catch(reject)
})
p2.then(n => {
// ...
}).catch(e => {
console.log('Never makes it here')
})
return p2
}
更简单地说:
async connect() {
try {
// The next line is where the error originates
await client.connect()
} catch (err) {
return console.log('Never makes it here')
}
}
将
client.connect()
替换为 throw new Error('client.connect() simulation')
一切都按其应有的方式进行。 client.connect()
在做什么,哪里捕获不到异常?
版本:(尽管在最新的节点版本上仍然发生)
$ node --version
v20.18.0
问题是,async/await 提供了一种通过简单的编写来编写 Promise/then 链(甚至只是回调)的方法,就好像所有异步操作都是同步的一样。但是,在幕后,它们仍然是异步的。
只是你的例子的过度简化
async function connect(){
throw "failed connect";
}
async function start(){
await connect();
dosomethingelse();
}
start();
重要的是要理解,这相当于
function start(){
connect().then(function(){
dosomethingelse();
})
}
这是对 JS 的一个精彩改进,因为有时您可能需要执行 10 个异步操作的序列。因此,使用简单的
;
分隔符按顺序编写它们很方便,就好像它是一个简单的 connect(); dosomething();
,而实际上是 connect(continuation); end this function
,延续是做某事。
但是,这仍然是一堆承诺,然后
所以,如果你现在添加一个 try/catch 块
async function connect(){
throw "failed connect";
}
async function start(){
try{
await connect();
}catch(e){
console.log("catch", e);
}
}
嗯,这还是现实
try{
connect().then(continuation)
}catch(e){
...
}
try
仅包含对异步 connect
的调用
有点像
try{
setTimeout(trytoconnect, 1000);
}catch(e){
}
不会尝试
trytoconnect
中发生的任何事情,你的 try/catch 没有理由捕获 connect
中发生的事情(除非错误发生在承诺本身的创建中,而不是在其执行中)