I have a function chain in a node 4.3
script that looks something like, callback -> promise -> async/await -> async/await -> async/await
like so:
const topLevel = (resolve, reject) => {
const foo = doThing(data)
.then(results => {
resolve(results)
})
.catch(err => {
reject(err)
})
}
async function doThing(data) {
const thing = await doAnotherThing(data)
return thing
}
async function doAnotherThing(data) {
const thingDone = await etcFunction(data)
return thingDone
}
(The reason it isn't async/await
all the way through is that the top level function is a task queue library, and ostensibly can't be run async/await
style)
If etcFunction()
throws, does the error
bubble up all the way to the top-level Promise
?
If not, how can I bubble-up errors
? Do I need to wrap each await
in a try/catch
and throw
from there, like so?
async function doAnotherThing(data) {
try {
await etcFunction(data)
} catch(err) {
throw err
}
}
I have a function chain in a node 4.3
script that looks something like, callback -> promise -> async/await -> async/await -> async/await
like so:
const topLevel = (resolve, reject) => {
const foo = doThing(data)
.then(results => {
resolve(results)
})
.catch(err => {
reject(err)
})
}
async function doThing(data) {
const thing = await doAnotherThing(data)
return thing
}
async function doAnotherThing(data) {
const thingDone = await etcFunction(data)
return thingDone
}
(The reason it isn't async/await
all the way through is that the top level function is a task queue library, and ostensibly can't be run async/await
style)
If etcFunction()
throws, does the error
bubble up all the way to the top-level Promise
?
If not, how can I bubble-up errors
? Do I need to wrap each await
in a try/catch
and throw
from there, like so?
async function doAnotherThing(data) {
try {
await etcFunction(data)
} catch(err) {
throw err
}
}
Share
Improve this question
edited Nov 30, 2016 at 15:12
Felix Kling
817k180 gold badges1.1k silver badges1.2k bronze badges
asked Nov 28, 2016 at 16:37
BrandonBrandon
7,96610 gold badges53 silver badges75 bronze badges
7
-
What is
makePromise
? – Bergi Commented Nov 28, 2016 at 16:51 -
"the top level function is a task queue library, and ostensibly can't be run async/await style" - there's no reason why a queue library couldn't use
async function
s as tasks. You really shouldn't have to deal with callbacks. If you need to use a particular queue library that employs callback style, use a wrapper function. – Bergi Commented Nov 28, 2016 at 16:53 -
@Bergi
makePromise
is actually anasync
function, but since it's called from a non-async
environment, i'm handling it like a promise. re: i agree, I'm going to try and promise-ify it eventually, but can I have reliable error bubbling in the mean time? – Brandon Commented Nov 28, 2016 at 16:58 -
@Bergi i removed the
makePromise
bit from the snippet to clarify--the first function called in the top-level is anasync function
i'm treating as a regularPromise
– Brandon Commented Nov 28, 2016 at 17:00 - 1 @Bergi yes, thanks for catching that & the other errors- i should've just copied the actual code instead of trying to recreate in pseudocode – Brandon Commented Nov 28, 2016 at 17:04
3 Answers
Reset to default 7If
etcFunction()
throws, does the error bubble up all the way through theasync function
s?
Yes. The promise returned by the outermost function will be rejected. There's no need to do try { … } catch(e) { throw e; }
, that's just as pointless as it would be in synchronous code.
… bubble up all the way to the top-level Promise?
No. Your topLevel
contains multiple mistakes. If you don't return
the doThing(data)
from the then
callback, it will be ignored (not even awaited) and the rejection stays unhandled. You'll have to use
.then(data => { return doThing(data); })
// or
.then(data => doThing(data))
// or just
.then(doThing) // remended
And in general, your function should look like this:
function toplevel(onsuccess, onerror) {
makePromise()
.then(doThing)
.then(onsuccess, onerror);
}
No unnecessary function expressions, no .then(…).catch(…)
antipattern (that could lead to onsuccess
and onerror
to both be called).
I know this question is old, but as your question is written, wouldn't the doAnotherThing()
function be unnecessary because it just wraps etcFunction()
?
So your code could be simplified to this:
async function topLevel(){
let thing = await doThing(data)
let thingDone = await etcFunction(data)
//Everything is done here...
}
//Everything starts here...
topLevel()
I just had a similar issue where my nested errors didn't appear to bubble up to my top level function.
The fix for me was to remove the "try / catch" from my nested function and allow the error to just be thrown.