I need to call 3 requests in sequence, all of them with 3 resolutions
Happy path would look like this:
const firstCallResponse = await this.service1.call1();
if (firstCallResponse) {
const secondCallResponse = await this.service2.call2();
if (secondCallResponse) {
const thirdCallResponse = await this.service3.call3();
if (thirdCallResponse) {
console.log('sequence finished successfully);
}
}
}
And it doesn't look that bad, but if I'll try to add those two fallbacks for every request, the code will become very messy.
try {
const firstCallResponse = await this.service1.call1();
if (firstCallResponse) {
try {
const secondCallResponse = await this.service2.call2();
if (secondCallResponse) {
try {
const thirdCallResponse = await this.service3.call3();
if (thirdCallResponse) {
console.log('sequence finished successfully');
} else {
console.log('do something, as third call response is not ok');
}
} catch {
console.log('do something as third call failed');
}
} else {
console.log('do something, as second call response is not ok');
}
} catch {
console.log('do something as second call failed');
}
} else {
console.log('do something, as first call response is not ok');
}
} catch {
console.log('do something as first call failed');
}
Is there a way to make this code more readable or elegant? The code above would work, but it doesn't look good and it's extremely hard to read. Thanks in advance!
First of all you can wrap more than one promise with try/catch if you want to do the same thing when they fail. Also accept argument in catch blocks since they can tell you where error originated / more info about it aka
try {
// await promise
} catch (errorName) {
// handle error
}
Other than that main thing I would recommend is reversing your logic with checking the results what to do next and adding return statements.
try {
const firstCallResponse = await this.service1.call1();
if (!firstCallResponse) {
console.log('do something as first call failed');
return;
}
const secondCallResponse = await this.service2.call2();
if (!secondCallResponse) {
console.log('do something as second call failed');
return;
}
// ...
// if no errors do something with all results
} catch {
console.log('do something as first call failed');
}
Another tip I would like to add for end is if your second call does not require anything from results of first call you can group them all in one promise with
await Promise.all([
this.service1.call1(),
this.service2.call2()
])