JavaScript error handling async function passed to reduce
I'm passing an async
function to an array reduce
function. What's the syntax for catching errors thrown by the passed in function? The reducing is happening inside a try
catch
block, which is catching other errors just fine, but node gives me an UnhandledPromiseRejectionWarning
if the passed in function itself throws an error.
Code:
aFunction = async (anArray) => {
try {
const result = await anArray.reduce(async (a, b) => {
await doSomethingTo(b);
}, Promise.resolve());
return result;
}
catch (error) {
winston.error(error);
}
}
(Edit) Actual code:
exports.chainedQueryDB = async (queries, finalTask, download) => {
let client = await pool.connect();
try {
winston.info(`Begin chained table query.`);
// Loop through query array
const result = await queries.reduce(async (a, b) => {
await client.query(b);
}, Promise.resolve());
if (download) {
return streamOut(download, client);
}
return result.rows;
}
catch (error) {
throw error;
}
finally {
const final = await client.query(finalTask);
winston.info(`Temp table dropped.`);
client.release();
}
}
(Edit) Report: Replacing await client.query(b)
with await a; return client.query(b);
await a; return client.query(b);
solved the problem. With just await client.query(b)
, reduce
seemed to 1) generate a bunch of floating client.query
calls that all ran even if an earlier promise was rejected, and 2) caused an unhandled promise rejection warning. Using await a; return client.query(b);
await a; return client.query(b);
stops execution on first rejection and the catch block catches the error as originally intended.
You need to do something with the promise in the accumulator (the a
parameter) as well - await
it, handle its errors by installing a .catch()
callback, wait for it concurrently with the doSomething(b)
. For a sequential execution, you could do
async function aFunction(anArray) {
try {
return await anArray.reduce(async (a, b) => {
await a; // make sure the previous query is done
return doSomethingTo(b);
}, Promise.resolve());
} catch (error) {
winston.error(error);
}
}
I would hover recommend to simply not use reduce
here:
async function aFunction(anArray) {
try {
let result;
for (const b of anArray) {
result = await doSomethingTo(b);
}
return result;
} catch (error) {
winston.error(error);
}
}
To avoid the UnhandledPromiseRejectionWarning
you can chain .catch()
to aFunction()
call or utilizing second parameter of .then()
to handle the rejected Promise
or error.
Alternatively, chain .catch()
to doSomethingTo(b)
call to handle the error.
上一篇: 检查一个对象是否有属性