How to Handle Errors in JavaScript | The School of Code

Settings

Appearance

Choose a typography theme that suits your style

Back to How-to Guides
JavaScript

How to Handle Errors in JavaScript

Learn how to use try/catch blocks and error handling patterns in JavaScript.

JavaScriptError HandlingExceptions

JavaScript uses try/catch blocks for error handling. Here’s how to use them effectively.

Basic Try/Catch

Catch and handle errors:

try {
  const result = JSON.parse("invalid json");
} catch (error) {
  console.log("Error parsing JSON:", error.message);
}

The finally Block

Always executes after try/catch:

try {
  // Attempt risky operation
  riskyOperation();
} catch (error) {
  console.log("Error:", error.message);
} finally {
  // Cleanup - always runs
  console.log("Cleanup complete");
}

Throwing Errors

Create and throw your own errors:

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

try {
  divide(10, 0);
} catch (error) {
  console.log(error.message); // "Cannot divide by zero"
}

Error Types

JavaScript has built-in error types:

// TypeError
try {
  null.toString();
} catch (e) {
  console.log(e instanceof TypeError); // true
}

// RangeError
try {
  const arr = new Array(-1);
} catch (e) {
  console.log(e instanceof RangeError); // true
}

// SyntaxError (caught during parsing)
// ReferenceError (undefined variable)

Custom Error Classes

Create your own error types:

class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

class InsufficientFundsError extends Error {
  constructor(balance, amount) {
    super(`Cannot withdraw ${amount}. Balance: ${balance}`);
    this.name = "InsufficientFundsError";
    this.balance = balance;
    this.amount = amount;
  }
}

function withdraw(balance, amount) {
  if (amount > balance) {
    throw new InsufficientFundsError(balance, amount);
  }
  return balance - amount;
}

try {
  withdraw(100, 150);
} catch (error) {
  if (error instanceof InsufficientFundsError) {
    console.log("Not enough funds:", error.balance);
  }
}

Handling Async Errors

With Promises:

fetch("https://api.example.com/data")
  .then(response => response.json())
  .catch(error => {
    console.log("Fetch error:", error.message);
  });

With async/await:

async function fetchData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    return data;
  } catch (error) {
    console.log("Error fetching data:", error.message);
    throw error; // Re-throw if needed
  }
}

Checking Error Types

try {
  // Some code
} catch (error) {
  if (error instanceof TypeError) {
    console.log("Type error occurred");
  } else if (error instanceof RangeError) {
    console.log("Range error occurred");
  } else {
    console.log("Unknown error:", error.message);
  }
}

Re-throwing Errors

Handle some errors, re-throw others:

try {
  someRiskyOperation();
} catch (error) {
  if (error instanceof ValidationError) {
    console.log("Validation failed:", error.message);
  } else {
    throw error; // Re-throw unexpected errors
  }
}

Summary

  • Use try/catch to handle synchronous errors
  • Use finally for cleanup code
  • Use throw new Error() to throw errors
  • Create custom error classes for specific error types
  • Use .catch() or try/catch with async/await for async errors