What Is It?

When a Promise rejects (throws an error) and there's no .catch() or try/catch around the await, you get an unhandled rejection. In Node.js this can crash the entire process. In browsers it shows in the console.

// ❌ Unhandled rejection
fetch('/api/data').then(res => res.json());
// If fetch fails, the rejection is unhandled

// ❌ async without try/catch
async function loadData() {
  const data = await fetch('/api/data').then(r => r.json());
  // If this throws, the rejection propagates up unhandled
}

Fixing with .catch()

// ✅ .catch() on the Promise chain
fetch('/api/data')
  .then(res => res.json())
  .then(data => render(data))
  .catch(err => {
    console.error('Failed to load:', err);
    showErrorMessage();
  });

// ✅ .catch() on the outermost Promise
Promise.all([fetchUsers(), fetchPosts()])
  .then(([users, posts]) => render(users, posts))
  .catch(err => handleError(err));

async/await Error Handling

// ✅ try/catch around all awaited calls
async function loadData() {
  try {
    const res = await fetch('/api/data');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();
    render(data);
  } catch (err) {
    console.error('Error:', err.message);
    showError(err.message);
  }
}

// ✅ Wrapper function for consistent handling
async function safeFetch(url, options) {
  try {
    const res = await fetch(url, options);
    if (!res.ok) throw new Error(`HTTP ${res.status}: ${url}`);
    return await res.json();
  } catch (err) {
    console.error('Fetch error:', err);
    return null;  // or throw; to propagate
  }
}

Global Unhandled Rejection Handler

// Browser — catch any missed rejections
window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled Promise rejection:', event.reason);
  event.preventDefault();  // prevents console error in some cases
});

// Node.js
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection:', reason);
  // In production: log to monitoring service, then exit gracefully
});
💡 Best practice: Use the global handler as a last resort safety net — it shouldn't be your primary error handling strategy. Catch errors at the source where you have context to handle them appropriately.