After searching on SO, I could not find an answer to this problem. All of the questions I saw, the error was still being caught. I’m having the inverse problem. No matter how I refactor the following code, I am STILL not able to catch the error.
I hope I’m just overlooking something or doing something wrong.
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!')
}
}
Output:
node:internal/process/promises:391
triggerUncaughtException(err, true /* fromPromise */);
^
Error: connect ECONNREFUSED 127.0.0.1:6090
I’ve rewritten connect()
as simple as possible in multiple different ways:
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
}
And even more simply:
async connect() {
try {
// The next line is where the error originates
await client.connect()
} catch (err) {
return console.log('Never makes it here')
}
}
Replacing await client.connect()
with throw new Error('client.connect() simulation')
Everything works as it should. What is client.connect()
doing, where the exception can not be caught?
Going as far as encapsulating the actual .connect
method, the exception still happens and node crashes. Example:
client.connect().then(() => {}).catch(err => console.error('We never make it here'))
Version: (Although still happens on latest node version)
$ node --version
v20.18.0
Client in question: bee-queue
bee-queue.connect function
3
Answers
Solved. The issue was not in my code. The issue was upstream in the
bee-queue
library. The promise was not being caught and rejected to the downstream promise chain.See this PR for more info: https://github.com/bee-queue/bee-queue/pull/878
The thing is, async/await offers a way to write a chain of promises/then (of even just callbacks) with a simple writing, as if all asynchronous operations were synchronous. But, still, under the hood, they are still asynchronous.
Just an over simplification of your example
It is important to understand, that this is the equivalent of
It is a wonderful improvement to JS, since sometimes you may have a sequence of 10 asynchronous operations to perform. So it is convenient to write them in sequence with just a plain
;
separator, as if it was a simpleconnect(); dosomething();
, when in reality isconnect(continuation); end this function
, continuation being that do something.But, still, it is a bunch of promises and
then
So, if you add a try/catch block now
Well, it is still in reality
the
try
englobes only the calls to asynchronousconnect
So a little bit like
wouldn’t catch anything happening in
trytoconnect
, your try/catch has no reason to catch what happens in yourconnect
(unless the error happens in the creation of the promise itself, not in its execution)As for a solution, you can find one here
Let me say this… You’re not doing it right…
async
functions always will return a promise. Then you must use.then()
and/or.catch()
on the async function call, even if you await for the fulfillment.try/catch
will never get the error because they run outside of this block context.Here’s a working example:
NOTE that
.then()
and.catch()
both return a different promise than the one they’re called upon. So, in the above example, first is parseddoSomething()
that returns a promise, then.then()
that returns another promise that fulfills if there’s no error indoSomething()
and.then()
, then.catch()
that returns another promise that fulfills ifdoSomething()
and.then()
produces no error or call the callback on.catch
if there’s any error and then returns what the callback returned. Only then, theawait
will retrieve the promise return value.There are those two other answers I gave to other questions that shows how to handle unhandled errors that may come from
setTimeout
, events and other async sources:https://stackoverflow.com/a/79189671/2804429
https://stackoverflow.com/a/79184566/2804429