DEV Community

Cover image for How to Handle Unhandled Exceptions & Unhandled Promise Rejections in JavaScript and React
Kiran
Kiran

Posted on

How to Handle Unhandled Exceptions & Unhandled Promise Rejections in JavaScript and React

๐Ÿšจ How to Handle Unhandled Exceptions & Unhandled Promise Rejections in JavaScript and React

One of the biggest differences between a demo app and a production app is error handling.

A good application doesn't just work when everything is fineโ€”it fails gracefully when something goes wrong.


๐Ÿง  1๏ธโƒฃ What is an Unhandled Exception?

An unhandled exception is an error that is thrown but never caught.

Example:

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

divide(10, 0); // โŒ Uncaught Error
Enter fullscreen mode Exit fullscreen mode

Since there's no try...catch, the application may crash or stop executing that code path.


โœ… Handle It with try...catch

try {
  divide(10, 0);
} catch (error) {
  console.error(error.message);
}
Enter fullscreen mode Exit fullscreen mode

โœ” Prevents the app from crashing unexpectedly.


๐Ÿง  2๏ธโƒฃ What is an Unhandled Promise Rejection?

When a Promise rejects and no .catch() (or try...catch with await) handles it.

fetch("/api/users")
  .then(res => res.json());

// โŒ No .catch()
Enter fullscreen mode Exit fullscreen mode

Or:

async function getUsers() {
  const res = await fetch("/api/users");
  return res.json();
}

// โŒ No try...catch
Enter fullscreen mode Exit fullscreen mode

โœ… Handle Async Errors Properly

async function getUsers() {
  try {
    const res = await fetch("/api/users");

    if (!res.ok) {
      throw new Error("Failed to fetch users");
    }

    return await res.json();
  } catch (error) {
    console.error(error);
  }
}
Enter fullscreen mode Exit fullscreen mode

โš›๏ธ 3๏ธโƒฃ Handling Errors in React

React Error Boundaries catch:

โœ” Rendering errors

โœ” Lifecycle errors

โœ” Constructor errors

Example:

<ErrorBoundary>
  <Dashboard />
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

๐Ÿšจ Error Boundaries DO NOT Catch

โŒ Event handler errors

<button onClick={() => {
  throw new Error("Boom");
}} />
Enter fullscreen mode Exit fullscreen mode

โŒ Async errors

setTimeout(() => {
  throw new Error("Boom");
}, 1000);
Enter fullscreen mode Exit fullscreen mode

โŒ Promise rejections

You must handle these yourself.


๐ŸŒ 4๏ธโƒฃ Global Error Handling (Browser)

You can listen for uncaught JavaScript errors:

window.addEventListener("error", (event) => {
  console.error("Unhandled Exception:", event.error);
});
Enter fullscreen mode Exit fullscreen mode

Useful for:

  • Logging
  • Monitoring
  • Crash reporting

๐ŸŒ 5๏ธโƒฃ Global Promise Rejection Handling

Handle promises that nobody caught:

window.addEventListener("unhandledrejection", (event) => {
  console.error("Unhandled Promise:", event.reason);
});
Enter fullscreen mode Exit fullscreen mode

This is commonly used to send errors to monitoring tools.


๐Ÿ“Š 6๏ธโƒฃ Log Errors to Monitoring Services

In production, don't just use:

console.error(error);
Enter fullscreen mode Exit fullscreen mode

Use tools like:

  • Sentry
  • Bugsnag
  • Datadog

These provide:

โœ” Stack traces

โœ” User sessions

โœ” Browser info

โœ” Release tracking


๐Ÿšจ Common Mistakes

โŒ Empty catch blocks

try {
  // code
} catch {}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‰ Silently ignores errors.


โŒ Swallowing errors

catch (error) {
  // do nothing
}
Enter fullscreen mode Exit fullscreen mode

Always log or handle them appropriately.


โŒ Assuming fetch() throws for HTTP errors

const res = await fetch("/users");
Enter fullscreen mode Exit fullscreen mode

A 404 or 500 does not throw. You should check:

if (!res.ok) {
  throw new Error("Request failed");
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ’ก Senior-Level Insight

A good error-handling strategy has multiple layers:

  • Local handling: try...catch for recoverable operations.
  • Component handling: Error Boundaries for UI rendering errors.
  • Global handling: window.onerror and window.onunhandledrejection.
  • Monitoring: Send errors to a centralized service instead of relying on console.error.

The goal isn't to hide errorsโ€”it's to capture them, recover when possible, and give users a graceful experience.


๐ŸŽฏ Interview One-Liner

Handle synchronous exceptions using try...catch, asynchronous errors using .catch() or try...catch with async/await, use React Error Boundaries for rendering errors, and implement global error listeners and monitoring tools to capture uncaught exceptions and promise rejections in production.


JavaScript #ReactJS #Frontend #ErrorHandling #WebDevelopment #InterviewPrep #EngineeringMindset #SoftwareEngineering

Top comments (0)