DEV Community

Cover image for Mastering Error Handling in JavaScript
Accreditly
Accreditly

Posted on

Mastering Error Handling in JavaScript

As developers, we all know that writing error-free code is nearly impossible. Errors are bound to happen, but it's how we handle them that matters. In this post, we'll dive into the world of error handling in JavaScript, discussing different techniques and best practices to make your code more robust and maintainable.

Introduction to Error Handling

JavaScript provides several built-in error objects, such as Error, TypeError, SyntaxError, ReferenceError, etc. When something goes wrong, these objects are thrown, allowing developers to react to the situation appropriately.

However, merely throwing an error isn't enough. We need to handle them gracefully, ensuring our application remains functional even in the face of adversity.

Try, Catch, and Finally

One of the most common ways to handle errors in JavaScript is using the try...catch statement. It allows you to execute a block of code and catch any errors that occur during its execution.

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

You can also include an optional finally block, which will always execute, regardless of whether an error was thrown or not.

try {
  // Code that may throw an error
} catch (error) {
  // Code to handle the error
} finally {
  // Code that will always execute
}
Enter fullscreen mode Exit fullscreen mode

Custom Errors

Sometimes, built-in error types don't provide enough information about the error. In such cases, you can create your own custom error classes by extending the Error object.

class MyCustomError extends Error {
  constructor(message) {
    super(message);
    this.name = 'MyCustomError';
  }
}

try {
  throw new MyCustomError('Something went wrong!');
} catch (error) {
  console.error(error.name + ': ' + error.message);
}
Enter fullscreen mode Exit fullscreen mode

Error handling with Promises

Promises are a popular approach for handling asynchronous operations in JavaScript. They have built-in error handling using the .catch() method, which is called when the Promise is rejected.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error fetching data:', error));
Enter fullscreen mode Exit fullscreen mode

Error handling with async/await

Async/await is another way to handle asynchronous operations in JavaScript. It works well with Promises and makes your code more readable by allowing you to write asynchronous code as if it were synchronous. To handle errors with async/await, simply wrap your code in a try...catch block.

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

fetchData();
Enter fullscreen mode Exit fullscreen mode

Best Practices

Here are some best practices for error handling in JavaScript:

  1. Use appropriate error types: Make use of built-in error types and create custom error classes when necessary. This helps you and other developers better understand the nature of the error.
  2. Don't suppress errors: Catching errors and not handling them properly can lead to silent failures, making debugging more challenging. Always handle errors gracefully, providing meaningful information when possible.
  3. Centralize error handling: Consider using a centralized error handling mechanism, such as an error handling middleware in Express.js or a global error event listener. This helps you maintain consistent error handling across your application.
  4. Log errors: Log errors for future reference and debugging purposes. Make sure to log enough information to help you understand the context in which the error occurred. Handle asynchronous errors: Don't forget to handle errors in asynchronous code, such as Promises and async/await functions. Failing to handle errors in these scenarios can lead to unhandled promise rejections and unexpected application behaviour.

Wrapping up

Error handling is an essential aspect of writing robust and maintainable JavaScript applications. By understanding and implementing different error handling techniques, you'll be better prepared to tackle any issues that arise in your code. Keep these best practices in mind as you work on your projects to ensure a more seamless and enjoyable development experience.

Further reading

If you found this post interesting, then take a look at our comprehensive guide to error handling in JavaScript.

Top comments (4)

Collapse
 
cheezery profile image
Carsten Dietzel

Thanks for this post! On our page we use a global error handling and try to log as much information as we can get. The handler is pretty simple, we just added an callback on window.onerror, where we try to get the message and stack from the error. but pretty often for example the stack is empty, which makes those logs pretty useless. We assume they come from either very old browsers or something like browser extensions or custom user scripts. How would you suggest handling that? Currently we just ignore every error, where the error stack is empty πŸ™ˆπŸ™‰ Thanks in advance!

Collapse
 
accreditly profile image
Accreditly • Edited

Hey @cheezery , that sounds pretty frustrating.

One option would be to implement a third-party error tracker. It depends on your stack as to what I'd recommend. We use Laravel heavily, which has something called Flare available that tracks client-side and server-side errors. The beauty of that is that you get better context of the errors, as you can get an overview of the full stack (eg. is the user logged in? What models/queries were called during the page load? etc).

Other options include Bugsnag, Sentry or NewRelic.

They're all paid products but most offer a trial period, and implementation is pretty trivial. It might be worth installing one on a trial and seeing if they're able to pick up more of the error than you are able to.

Ultimately though, you may be right, and some errors are just too mysterious to track down. If you aren't getting any user reports of issues then it's entirely possible these errors are caused by something peculiar you just can't account for (some weird headless browser with a masked user agent, maybe?).

One other option, which really depends on whether you think this is a legitimate issue or not, is to include some kind of screen recording tool. Massive warning here this is a potential privacy issue, so ensure you're comfortable with it. The strategy might be to call the recording tool when the error occurs to try and understand what users are doing just after it happens. Of course it's better to know what's happening before it happens, but that would mean recording everyone's session, which isn't very desirable. Microsoft have a free analytics package that can record sessions for playback, it's pretty basic but it works. I think it works by making a log of mouse position, elements clicked, etc, rather than actually recording their screen (which would likely need additional permissions).

Hope this helps. It's difficult to offer specific advice more than what I've put above without being in the scenario myself!

Collapse
 
cheezery profile image
Carsten Dietzel

Hi @accreditly,

thanks a lot for your help. Your suggestion to implement a third-party error tracker is very interesting. I'll definitely check thos libraries out.
And it's true with that limited information it's hard to make suggestions. But thanks again for taking the time to offer your expertise. Your suggestions have been really helpful, and I appreciate it a lot.

Thread Thread
 
accreditly profile image
Accreditly

No problem :) happy to help