A save button calls an API, the request fails, the error appears in the console - and the UI still shows 'Saved'. Walk me through what is actually happening in that promise chain.
A catch handler that returns normally converts a rejected promise into a fulfilled one, so every then after it runs as though nothing failed. Combined with fetch, which only rejects on network errors and resolves happily on a 500, the chain reports success twice over. Fix by re-throwing from catch, checking response.ok, and modelling UI state as a machine.
Answer
Short answer
catch does not stop a chain — it handles the rejection, and a handler that returns normally produces a fulfilled promise. Every .then after it therefore runs on the success path. The error was genuinely caught, genuinely logged, and then genuinely swallowed, and the chain continued as if the call had worked.
Was this answer helpful?
Likely follow-ups
- Move the catch to the very end of the chain. Does that fix it, and what does it change about error granularity?
- What is the difference between .then(onOk, onErr) and .then(onOk).catch(onErr)?
- The same code written with async/await - where does this bug live there?
- You use Promise.all for three saves and one fails. What does the user see, and what do you want them to see?
- How would you catch this class of bug automatically rather than in review?
Related questions
- A promise rejects and nothing is awaiting it. What does Node do?hardAlso on promises and async4 min
- Here is a script mixing setTimeout, a promise chain and an await. Tell me the order the logs come out in, and why.mediumAlso on promises and javascript4 min
- A client disconnects but your server keeps working on their request. How does cancellation actually propagate in .NET?mediumAlso on async4 min
- How is `this` determined in JavaScript, and why does a method lose it when you pass it as a callback?mediumAlso on javascript4 min