You can go by what Rahul has suggested, its called as Promise chaining.
Modern javascript has new concepts that allow you to handle these complex requirements without making you go in promise chaining callback hell.
Welcome Async and Await :)
await - > The keyword await makes JavaScript wait until that promise
settles and returns its result.
async - > The word “async” before a function means one simple thing: a
function always returns a promise. Other values are wrapped in a
resolved promise automatically.
So your code will be something like:
async function doComplexCallout() {
let responseFromApi1 = await fetch('https://salesforce.stackexchange.com/');
let responseFromApi2 = await doApexCall(responseFromApi1.data); //sending response of first call to second.
}
Async and await are completely supported by lwc and modern browser as mentioned here
async/await functions in LWC
src: https://javascript.info/async-await
Regarding logging: You can put the code of async function inside the try-catch block and log whenever error happens and promise is not resolved.
Src: https://itnext.io/error-handling-with-async-await-in-js-26c3f20bc06a