JavaScript Error Handling

JavaScript Error Handling

Errors happen in code, and knowing how to handle them makes your programs more reliable. JavaScript has built-in ways to catch and deal with problems so your app doesn’t crash. Let’s learn about error handling.

What Are Errors?

Errors are problems that stop your code from running normally. They can come from:

  • Mistakes in your code (like trying to access a property that doesn’t exist)
  • User input issues
  • Network problems
  • File system issues

When an error occurs, JavaScript throws an exception, which you can catch and handle.

The try...catch Statement

The basic way to handle errors is with try and catch:

try {
  // Code that might cause an error
  let result = someFunction();
  console.log(result);
} catch (error) {
  // Code to run if an error occurs
  console.log('An error occurred:', error.message);
}

The code in try runs normally. If an error happens, execution jumps to catch, and the error object is passed as a parameter.

The finally Block

finally runs whether there’s an error or not. It’s great for cleanup:

let file;

try {
  file = openFile('data.txt');
  // Process the file
  processData(file);
} catch (error) {
  console.log('Error processing file:', error.message);
} finally {
  // This always runs
  if (file) {
    file.close();
  }
}

Throwing Your Own Errors

You can throw errors yourself using the throw statement:

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

try {
  let result = divide(10, 0);
} catch (error) {
  console.log(error.message); // Outputs: Cannot divide by zero
}

You can throw any value, but it’s best to throw Error objects for consistency.

Different Types of Errors

JavaScript has built-in error types:

  • Error: General error
  • SyntaxError: Code syntax problems
  • ReferenceError: Accessing undefined variables
  • TypeError: Wrong type operations
  • RangeError: Values out of range
try {
  let obj = {};
  obj.nonExistent(); // This will throw TypeError
} catch (error) {
  if (error instanceof TypeError) {
    console.log('Type error occurred');
  } else {
    console.log('Other error:', error.message);
  }
}

Best Practices for Error Handling

  1. Don’t catch everything: Only catch errors you know how to handle. Let unexpected errors bubble up.

  2. Provide helpful messages: When throwing errors, include clear messages about what went wrong.

  3. Use finally for cleanup: Close files, release resources, etc.

  4. Log errors: In production, log errors so you can debug issues.

function safeDivide(a, b) {
  try {
    if (typeof a !== 'number' || typeof b !== 'number') {
      throw new TypeError('Both arguments must be numbers');
    }
    if (b === 0) {
      throw new Error('Division by zero');
    }
    return a / b;
  } catch (error) {
    console.error('Error in safeDivide:', error.message);
    // You could return a default value or re-throw
    throw error; // Re-throw to let caller handle it
  }
}

Asynchronous Error Handling

For async code like promises, error handling is different. You’ll learn about that in JavaScript promises and async/await.

For now, remember that errors in callbacks need to be handled in the callback:

setTimeout(function() {
  try {
    riskyOperation();
  } catch (error) {
    console.log('Error in timeout:', error.message);
  }
}, 1000);

Error handling is crucial for robust applications. Start by wrapping risky code in try...catch, and gradually learn more advanced patterns.

The MDN Error reference has more details on built-in error types and methods.

Last updated on