Skip to content

Instantly share code, notes, and snippets.

@sjkillen
Last active August 15, 2018 19:15
Show Gist options
  • Save sjkillen/267132a45dc3fd2c917a2d601acf3f17 to your computer and use it in GitHub Desktop.
Save sjkillen/267132a45dc3fd2c917a2d601acf3f17 to your computer and use it in GitHub Desktop.
let rejectA;
const promA = new Promise((_, _reject) => rejectA = _reject);
let rejectB;
const promB = new Promise((_, _reject) => rejectB = _reject);
async function* foo() {
try {
await promA.finally(() => console.log("Promise A no longer pending"));
await promB.finally(() => console.log("Promise B no longer pending"));
} catch (e) {
console.log("Caught error: ", e);
}
// Catch errors indefinitely
for (; ;) {
try {
yield 5;
} catch (e) {
console.log("Caught error: ", e);
}
}
}
const a = foo();
a.next();
a.throw("Injected error");
rejectA("Error A");
rejectB("Error B");
@sjkillen
Copy link
Author

I can only guess that the execution trace is as follows:
Excute foo
Hit await promA, promA is pending so the function stops after it registers the finally handler on promA (Which will execute when the promise is no longer pending without changing the state of the promise from resolved/rejected)
An error (Injected Error) is injected into the function, but it's still waiting for a promise, this injected error is tucked away somewhere?
promA gets rejected and the error bubbles up into foo (taking precedence over Injected Error for some reason) then the error is caught in the first handler and the function resumes regular execution until it hits "yield" for the first time, then it remembers InjectedError all of a sudden and decides to throw that
No handlers ever got attached to promB so when it is rejected that error just gets thrown in the global async scope and node.js emits a warning. No more errors get caught by foo's loop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment