Error Handling in JavaScript: Try, Catch, Finally
Error handling in JavaScript isn’t just about avoiding crashes — it’s about controlling failure in a predictable way so your app behaves well even when something goes wrong.
In my experience, most bugs in real projects are not because logic is wrong, but because errors are not handled properly.
Let’s break this down cleanly 👇
🔹 1. What errors are in JavaScript
Errors are problems that stop your code from running correctly.
✅ Common types of errors
🔸 Syntax Error (code is invalid)
if (true {
console.log("Hello");
}
👉 Missing ) → code won’t even run
🔸 Reference Error (variable not defined)
console.log(x);
🔸 Type Error (wrong operation)
null.toUpperCase();
🔸 Runtime Error (error during execution)
JSON.parse("invalid json");
🔹 2. Using try...catch
👉 Lets you handle errors without crashing the app
try {
const data = JSON.parse("invalid json");
} catch (error) {
console.log("Something went wrong:", error.message);
}
🔑 Flow
try→ run code- if error → jump to
catch - app continues running
🔹 3. The finally block
👉 Runs no matter what (error or not)
try {
console.log("Trying...");
} catch (e) {
console.log("Error!");
} finally {
console.log("Always runs");
}
💡 Use cases
- closing DB connection
- stopping loaders
- cleanup tasks
🔹 4. Throwing custom errors
👉 You can create your own errors using throw
function withdraw(balance, amount) {
if (amount > balance) {
throw new Error("Insufficient balance");
}
return balance - amount;
}
Catch it
try {
withdraw(100, 200);
} catch (e) {
console.log(e.message);
}
🔹 Custom error types (advanced)
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
👉 I usually use custom errors when I want better control over different error types.
🔹 5. Why error handling matters
This is the real reason 👇
✅ 1. Prevent app crashes
Without handling:
JSON.parse("bad"); // app breaks ❌
With handling:
try {
JSON.parse("bad");
} catch {
console.log("Handled");
}
✅ 2. Better user experience
Instead of showing:
👉 App crashed
We can show:
👉 "Something went wrong, try again"
✅ 3. Debugging becomes easier
catch (e) {
console.log(e.message);
}
✅ 4. Control program flow
if (!user) {
throw new Error("User not found");
}
✅ 5. Security (important)
Don’t expose internal errors:
catch (e) {
res.status(500).send("Server error");
}
👉 This is important when working with backend APIs.
⚠️ Common mistakes
❌ Catching but ignoring
catch (e) {}
👉 This hides bugs 😬
❌ Using try/catch everywhere
👉 Use it only where errors are expected:
- API calls
- JSON parsing
- async operations
❌ Not handling async errors properly
try {
await fetchData();
} catch (e) {}
👉 This works only with async/await, not with .then()
❌ Not returning or rethrowing errors
try {
riskyTask();
} catch (e) {
console.log(e);
}
👉 Sometimes you should rethrow:
catch (e) {
throw e;
}
💡 Final takeaway
- Errors = things that break your code
try...catch= safely handle themfinally= always runsthrow= create your own errors- Good error handling = stable + professional apps