3 years into web development and I just discovered fetch API catch doesn't handle HTTP status errors

I can’t believe I’m just learning this now. The catch block in fetch API doesn’t actually catch HTTP error responses like 404 or 500 status codes. It only catches network failures and JavaScript errors.

I’ve been coding for over 3 years thinking that catch would handle all the bad responses from my API calls. Turns out I need to manually check the response.ok property or status codes to handle HTTP errors properly. This explains why some of our error handling wasn’t working as expected.

Anyone else make this same mistake? I feel pretty silly right now but I guess it’s better to learn late than never. Now I need to go back and fix a bunch of our API calls to handle HTTP errors correctly.

Don’t feel silly about this at all. The fetch API behavior is genuinely counterintuitive compared to other HTTP libraries like axios which throw errors for bad status codes by default. I made the exact same discovery about 2 years into using fetch and had to refactor quite a bit of code too. What helped me was creating a small wrapper function that checks response.ok and throws an error if it’s false, then I could use that consistently across projects. The MDN documentation mentions this behavior but it’s easy to miss when you’re learning. At least you caught it now rather than having it cause issues in production later on.

oh man this is such a classic gotcha! i remmeber banging my head against the wall for like 3 hours debugging what i thought was broken error handling. turns out fetch just silently returns sucessful promises even when the server sends back 404s or 500s. really wish the spec had made this more obvious from the start tbh

This caught me off guard too when I first encountered it. The fetch API design philosophy is different from what most developers expect - it treats HTTP error status codes as successful network operations since the server did respond, just with an error status. I remember debugging for hours wondering why my error handling wasn’t triggering for 401 responses. The key insight is that fetch only rejects the promise for actual network failures like connection timeouts or DNS resolution issues. For HTTP errors, you need to explicitly check the response status. I eventually started using a pattern where I immediately check response.status in the then block and throw a custom error if needed. It’s definitely one of those JavaScript quirks that trips up experienced developers.