So I have this async
function where I make multiple calls to NodeJS's DNS Api
. The first two calls return data but because of the third one, the catch block triggers and I don't get the data from the first two.
As it all depends on the type of query(netflix.com
), some of the await operations might throw an error because of no data. But what I want is I want to get data from the other calls even if there are errors from some of them.
Here's the code:
const dnsResolve = async () => {
const query = 'netflix.com';
try{
const aRecord = await dns.resolve4(query);
const aaaaRecord = await dns.resolve6(query);
const cnameRecord = await dns.resolveCname(query);
console.log(aRecord);
console.log(aaaaRecord);
console.log(cnameRecord);
}catch(err) {
console.log(err);
}
}
dnsResolve();
The above code returns
Error: queryCname ENODATA netflix.com
at QueryReqWrap.onresolve [as oncomplete] (internal/dns/promises.js:167:17) {
errno: undefined,
code: 'ENODATA',
syscall: 'queryCname',
hostname: 'netflix.com'
}
Individual outputs from the first two queries:
aRecord: [
{ address: '51.73.1.12' },
{ address: '55.83.62.128' },
{ address: '12.12.82.118' }
]
aaaaRecord: [
{ address: '2406:da200:ff00::222c0:598a' },
{ address: '24206:da00:ff00::22c2:44203' },
{ address: '2406:da0e0:ff00::36de2:41fd' }
]
How I want to display the data:
[
{ address: '51.73.1.12' },
{ address: '55.83.62.128' },
{ address: '12.12.82.118' },
{ address: '2406:da200:ff00::222c0:598a' },
{ address: '24206:da00:ff00::22c2:44203' },
{ address: '2406:da0e0:ff00::36de2:41fd' },
{ NO CNAME RECORDS }
]
Please note that there will be around 6 calls to the DNS API
. It cannot be determined which one will trigger an error because of no data. It totally depends on the query.
If a promise resolves normally, then await promise returns the result. But in the case of a rejection, it throws the error, just as if there were a throw statement at that line. In real situations, the promise may take some time before it rejects. In that case there will be a delay before await throws an error.
In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).
Using catch() on the Function Call Remember that async functions always return promises. This promise rejects if any uncaught error occurs in the function. If your async function body returns a promise that rejects, the returned promise will reject too.
This is the very use case Promise.allSettled
is for:
const results = await Promise.allSettled([
dns.resolve4(query),
dns.resolve6(query),
dns.resolveCname(query),
]);
for (const {status, value, reason} of results) {
if (status === "fulfilled") {
// Promise was fulfilled, use `value`...
} else {
// Promise was rejected, see `reason` for why...
}
}
Or if you only want the successful results:
const results = await Promise.allSettled([
dns.resolve4(query),
dns.resolve6(query),
dns.resolveCname(query),
]);
const values = results.filter(({status}) => status === "fulfilled")
.map(({value}) => value);
// ...use `values`...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With