How is this exception handled? (throw inside a callback inside a promise) [duplicate]
This question concerns some nodejs code. I am trying to clear my mind on how exceptions are handled, and how promise/async functions are alike/unlike.
I have greatly simplified my code, providing a (non-functional) sample below. I have a function (uploadFile) returning a promise. That function calls another async function which throws an exception.
const Linebyline = require('line-by-line');
const uploadFile = (filename) => new Promise((resolve, reject) => {
console.log(`Upload ${filename}`);
const lr = new Linebyline(filename);
//
// Point A: throw from here works, no unhandled rejection
//
lr.on('line', async (line) => {
// Another async function throws an error here,
// replacing it with a simple "throw" to clarify things:
throw new Error("failed");
// Point B: this throw fails, unhandled rejection
}
// Other code continues, calling resolve and reject...
}
async function top() {
try {
await uploadFile('test.txt');
} catch (err) {
console.log(`Err: ${err}`);
}
}
With this scheme, I get an unhandled rejection. Since I have a try/catch in the upper level function calling uploadFile, I wax expecting that catch to handle pretty much everything going wring in sub calls.
If I catch the "throw" inside uploadFile and transform it into a reject, then all is fine.
Obviously, not calling reject, I am looking for trouble, but I don't really understand the chain of events generated by that "throw"?
Thank you.
Edit, 01/31/2019
Edited the source code, to outline the core issue. When my function throws from point B (inside the callback), I end up with an unhandled rejection. When throwing from A, no unhandled rejection.
The core of the question is really what happens to that exception thrown from point B.
This code sample doesn't call resolve/reject, but this is done elsewhere in the real code.
You're using Promise constructors wrong. You should be calling reject
on error or resolve
on success. You're doing neither. If you just call reject
in your promise, then await
will throw the error, which is what you're trying to make happen here.