Skip to main content

Command Palette

Search for a command to run...

Error Handling in JavaScript: Try, Catch, Finally

Updated
5 min read

When writing JavaScript code, errors are unavoidable. Whether you're building a small project or a large-scale application, things can go wrong—unexpected inputs, failed API calls, or bugs in logic.

But what separates a beginner from a professional developer is not avoiding errors—it's handling them properly.

In this blog, we’ll explore:

  • What errors are in JavaScript

  • How to use try and catch

  • The role of the finally block

  • Throwing custom errors

  • Why error handling is important in real-world applications


🔹 What Are Errors in JavaScript?

In simple terms, errors are problems that occur while a program is running. These errors can stop your program or cause unexpected behavior.


✅ Example of a Runtime Error

let result = 10 / x; // x is not defined
console.log(result);

❌ Output:

ReferenceError: x is not defined

This is a runtime error, meaning it happens when the code is executed.


🔍 Types of Errors in JavaScript

  1. Syntax Errors

    • Occur when code is written incorrectly
    console.log("Hello" // missing bracket
    
  2. Runtime Errors

    • Occur during execution
    let num = undefined;
    console.log(num.toUpperCase()); // error
    
  3. Logical Errors

    • Code runs, but gives wrong output
    let total = 10 + "5"; // "105" instead of 15
    

🔹 Why Error Handling Matters

Without proper error handling:

  • Your application may crash ❌

  • Users get a bad experience 😕

  • Debugging becomes difficult 🔍

With error handling:

  • You can gracefully handle failures

  • Show meaningful messages to users

  • Keep your app running smoothly


🔹 What is Graceful Failure?

Instead of crashing your app, you handle the error and continue execution.

👉 Example:

try {
  let data = JSON.parse("invalid json");
} catch (error) {
  console.log("Something went wrong, please try again.");
}

✔️ The program doesn't crash—it handles the issue properly.


🔹 Using try and catch

The try...catch block allows you to test code for errors and handle them safely.


✅ Basic Syntax

try {
  // Code that may throw an error
} catch (error) {
  // Code to handle the error
}

✅ Example

try {
  let num = undefined;
  console.log(num.toUpperCase());
} catch (error) {
  console.log("Error occurred:", error.message);
}

✔️ Output:

Error occurred: Cannot read properties of undefined

🔍 Diagram Idea: Error Handling Flow

Start
  ↓
Try Block Executes
  ↓
Error?
 /   \
Yes   No
 |     |
Catch  Continue
 |
Finally (always runs)

🔹 The finally Block

The finally block is always executed, whether an error occurs or not.


✅ Syntax

try {
  // risky code
} catch (error) {
  // handle error
} finally {
  // always runs
}

✅ Example

try {
  console.log("Trying...");
  let result = 10 / 2;
} catch (error) {
  console.log("Error:", error.message);
} finally {
  console.log("Execution completed.");
}

✔️ Output:

Trying...
Execution completed.

💡 Use Cases of finally

  • Closing database connections

  • Stopping loaders/spinners

  • Cleaning up resources


🔹 Throwing Custom Errors

Sometimes, JavaScript doesn’t throw an error—but you want to enforce rules.

For that, we use the throw keyword.


✅ Basic Example

function checkAge(age) {
  if (age < 18) {
    throw new Error("You must be 18 or older.");
  }
  return "Access granted";
}

try {
  console.log(checkAge(16));
} catch (error) {
  console.log(error.message);
}

✔️ Output:

You must be 18 or older.

🔍 Why Use Custom Errors?

  • Validate user input

  • Enforce business rules

  • Provide meaningful error messages


🔹 Real-World Use Cases


✅ 1. Handling API Calls

async function fetchData() {
  try {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.log("Failed to fetch data");
  } finally {
    console.log("Request completed");
  }
}

✅ 2. Input Validation

function divide(a, b) {
  if (b === 0) {
    throw new Error("Cannot divide by zero");
  }
  return a / b;
}

✅ 3. File or Data Parsing

try {
  let obj = JSON.parse('{"name": "Kanishka"}');
  console.log(obj.name);
} catch (error) {
  console.log("Invalid JSON format");
}

🔹 Execution Order: Try → Catch → Finally

Let’s clearly understand the flow:


✅ Case 1: No Error

try {
  console.log("No error");
} catch (e) {
  console.log("Catch block");
} finally {
  console.log("Finally block");
}

✔️ Output:

No error
Finally block

✅ Case 2: Error Occurs

try {
  throw new Error("Oops!");
} catch (e) {
  console.log("Caught:", e.message);
} finally {
  console.log("Finally block");
}

✔️ Output:

Caught: Oops!
Finally block

🔹 Common Mistakes to Avoid


❌ Ignoring Errors

try {
  riskyCode();
} catch (e) {}

👉 Always log or handle errors properly.


❌ Overusing try-catch

Avoid wrapping everything in try-catch. Use it only where errors are expected.


❌ Not Using Error Messages

catch (e) {
  console.log("Error");
}

👉 Better:

console.log(e.message);

🔹 Debugging Benefits

Error handling helps in:

  • Identifying bugs quickly

  • Understanding where things failed

  • Improving code quality

👉 Use:

console.error(error);

for better debugging.