I am developing an Excel add-in using the Office JS API. I have a taskpane which is running code similar to the following:
var failA = true
var failB = true
// In reality this is Excel.run, and it injects a context
async function run(f) {
f()
}
// Simulate a failing async call
async function fail(message, delay) {
setTimeout(()=>{
throw new Error(message)
}, delay)
}
// Simulate a successful async call
async function success(message, delay) {
setTimeout(delay)
}
async function doA() {
console.log("Inside A");
if (failA) {
console.log("Failing A");
await fail("Error A", 1000)
} else {
success("Success A")
}
console.log("Done A")
}
async function doB() {
console.log("Inside B");
if (failB) {
console.log("Failing B");
await fail("Error B", 1000)
} else {
success("Success B")
}
console.log("Done B")
}
async function main () {
try {
// This is how Excel.run is called in all the Office samples
await run(async ()=>{
console.log("Start main");
await doA();
console.log("Between A and B");
await doB();
console.log("Finished");
})}
catch (error) {
console.log("ERROR: " + error.message)
}
}
// Need to await main in an async context. In reality main is run from a button
(async () => await main())()
.as-console-wrapper { min-height: 100%!important; top: 0; }
I would expect the error in doA to bubble up and interrupt further execution of doB. The output should then be:
Start main
Inside A
Failing A
ERROR: Error A
Instead what I get is:
Start main
Inside A
Failing A
Done A
Between A and B
Inside B
Failing B
Done B
Finished
followed by two uncaught exceptions Error A and Error B.
What am I doing wrong? Can I achieve the behavior I expect without wrapping doA and doB separately in try...catch blocks?
fail()andsuccess()functions must return Promise instances, and resolve or reject those when the timer fires.throwin an asynchronously executed callback (like withsetTimeout) will not affect the promise returned by theasyncfunction.throwonly affects the current callstack. Despite the comment, you're not simulating a failing async call.