beginner

Handling errors


JavaScript errors can occur for various reasons, such as incorrect syntax, runtime issues, or unexpected data. When an error occurs, JavaScript throws an exception, which can interrupt the normal flow of your program.

Common Types of Errors

  1. Syntax Errors: These occur when there’s a mistake in the code structure. The interpreter can’t understand the script due to a typo or misplaced character.

  2. Runtime Errors: These happen during the execution of the code and are often caused by unexpected conditions, like dividing by zero or trying to access an undefined variable or any other custom defined errors as we will see in this post.

  3. Logic Errors: These are the trickiest to catch. Your code runs without any error, but it doesn’t produce the expected result due to a flaw in the algorithm or logic.

Throwing an Error

Errors can be thrown by the application itself but we can also do it whenever we want using throw keyword. For this we can use built in Error class but first we need to instantiate it so our full error throwing looks like throw new Error(<message>).

const user = { name: "John", age: 17 };

const canVote = function (user) {
  const minimumAge = 18;
  if (user.age < minimumAge) {
    throw new Error(`User ${user.name} is below ${minimumAge} and can't vote.`);
  }
};

canVote(user); // throws an error
/*
Uncaught Error: User John is below 18 and can't vote.
    at canVote (<anonymous>:6:11)
    at <anonymous>:12:1
*/

Using try, catch, and finally

JavaScript provides a powerful mechanism for handling errors using the try, catch, and finally blocks.

  • The try block contains the code that might throw an exception.
  • If an exception occurs, the catch block is executed, allowing you to handle the error gracefully.
  • The finally block is optional and executes whether an exception was thrown or not.
try {
  // ...
} catch (error) {
  // Handle the exception
  console.error("An error occurred:", error.message);
} finally {
}

Creating Our Own Errors

We can create our own errors by extending previously mentioned Error class. Error class has 3 different properties (name,message and stack) that we can change in our child error.

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

const user = { name: "John", age: 17 };

const canVote = function (user) {
  const minimumAge = 18;
  if (user.age < minimumAge) {
    throw new YearError(
      `User ${user.name} is below ${minimumAge} and can't vote.`,
    );
  }
};

canVote(user); // throws an error
/*
Uncaught YearError: User John is below 18 and can't vote.
    at canVote (<anonymous>:13:11)
    at <anonymous>:19:1
*/

Logging and Debugging

Logging is a crucial aspect of error handling. Utilize console.log() or other logging mechanisms to track the flow of your code and identify potential issues.

try {
  // Code that might throw an exception
  // ...
} catch (error) {
  // Log the error for debugging
  console.error("An error occurred:", error);
}

What Now?

Now you have even more control over your code handling and execution. Try and make an if else statement in the catch to execute different code depending on what error was thrown.

Previous Improving our example (2)
Next Creating server