Try Catch With Async Await
The last post left async/await with no error handling at all. .catch() doesn't attach to it the same way, but try/catch, plain JavaScript from long before Promises existed, does.
The last post left whereAmI with no error handling at all. .catch() doesn't attach to await the way it attaches to .then(), but try/catch does the job, and it isn't even an async feature.
try/catch Predates async/await Entirely
try/catch has been in JavaScript since long before Promises existed. It wraps ordinary code, catches whatever error happens inside, and keeps the script from dying because of it.
Hit Run. Reassigning a const is a real error, age is not just a suggestion, and without the try block it would stop the script entirely. Inside one, the catch block gets the error object and the script keeps going.
Wrapping whereAmI in try/catch
Nothing about the async function's logic changes, the whole body just moves inside a try block, and a catch block replaces the missing error handling from last post.
Hit Run. A genuine failure, permission denied, a rate-limited geocoding request, no longer takes the whole function down with it, it lands in catch and gets shown to the user instead.
The Same Old Gotcha, Still True Here
That manual if (!resGeo.ok) throw new Error(...) line exists for the exact reason from post 10: fetch only rejects on a real network failure, never on a bad status code. A 403 from hitting the geocoding API's rate limit is still a fulfilled response as far as fetch is concerned, async/await changes nothing about that fact, it just changes how the check reads.
The country lookup doesn't need its own check here, getJSON already throws internally, and a throw anywhere inside a try block, including one nested inside a function try is calling, lands in that same catch.
ExpandA rejection propagates down through the chain until something catches it, whether that rejection came from a real network failure or a manual throw.
A thrown error works the same way here: it doesn't matter how deep inside the try block it happens, it propagates outward exactly like a Promise rejection does, until the nearest catch picks it up.
finally Still Works the Same Way
try/catch has an optional third block, finally, and it runs whether the try succeeded or the catch caught something, the exact same job .finally() did on a Promise chain. The opacity fade-in belongs there for the same reason it always has: it has to happen either way.
The Essentials
try/catchis plain JavaScript, older than Promises, not something built specifically forasync/await.- Wrapping an async function's body in
tryand adding acatchblock is the actual replacement for.catch(). fetchstill only rejects on a real network failure, anif (!response.ok) throw new Error(...)check is still needed for a bad status,async/awaitdoesn't change that rule.- A
throwinside atryblock lands in that block'scatch, whether it happens directly or inside a function thetryblock calls. finallyruns regardless of success or failure, same job as a Promise chain's.finally(), just spelled differently.
Keep reading