JavaScript · Lesson 52
JavaScript Error Handling
try, catch, finally — stop your app from crashing and handle errors like a professional developer.
Every developer has seen this before — you open a website and the whole page breaks. A white screen. Nothing. This happens because someone did not handle errors properly. Error handling is what separates beginner code from production-ready code. After this guide your apps will never crash silently again.
What is Error Handling?
Error handling means catching problems before they crash your app. Instead of letting an error break everything — you catch it, handle it gracefully, and keep your app running.
JavaScript gives you three keywords for this: try, catch, and finally.
Quick Reference
| Keyword |
What It Does |
When It Runs |
| try |
Code that might fail |
Always runs first |
| catch |
Handle the error |
Only if error occurs |
| finally |
Cleanup code |
Always runs — error or not |
| throw |
Create your own error |
When you call it |
1. try...catch — The Basic Pattern
Put risky code inside try. If it fails, the catch block runs and receives the error object.
// Basic try...catch
try {
// risky code here
const data = JSON.parse('invalid json');
} catch (error) {
// handle the error
console.log('Something went wrong:', error.message);
}
// Without try...catch — app CRASHES
// With try...catch — app keeps running ✅
2. finally — Always Runs
finally runs no matter what — whether there was an error or not. Perfect for cleanup like hiding a loading spinner.
// Real example — API call with loading
async function fetchData() {
showSpinner(); // show loading
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Failed to fetch:', error.message);
} finally {
hideSpinner(); // always hide loading ✅
}
}
3. throw — Create Your Own Errors
Use throw to create custom errors when something goes wrong in your logic — like invalid user input.
// Custom validation error
function divide(a, b) {
if (b === 0) {
throw new Error('Cannot divide by zero!');
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (error) {
console.log(error.message); // Cannot divide by zero!
}
Pro Tips
Pro Tip #1 — Always wrap API calls
Any time you fetch data from an API — always wrap it in try...catch. Networks fail. Servers go down. APIs return unexpected data. Always assume it can fail and handle it gracefully.
Pro Tip #2 — Use error.message not just error
When you catch an error, use error.message to get the readable description. Just logging error gives you the full Error object which is harder to read in production logs.
Pro Tip #3 — Never leave catch empty
An empty catch block is worse than no error handling. At minimum always console.log the error so you know what went wrong. Silent failures are the hardest bugs to debug.
Quick Reference Cheatsheet
// Basic pattern
try {
// risky code
} catch (error) {
console.log(error.message);
} finally {
// always runs
}
// Throw custom error
throw new Error('Something went wrong');
// Async error handling
async function getData() {
try {
const res = await fetch(url);
const data = await res.json();
return data;
} catch (error) {
console.log('Error:', error.message);
}
}
Want daily web dev tips?
Follow Muhammad Waheed Asghar for daily JavaScript and CSS tips!