Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Unhandled Promise Rejection - Complete Fix Guide (2026)

What is Unhandled Promise Rejection?

Unhandled Promise Rejection occurs when a Promise is rejected but there's no .catch() handler or try-catch block to handle the error. This can lead to silent failures and hard-to-debug issues in your application.

Common Causes

  • Missing .catch() handler on promises
  • No try-catch block in async/await functions
  • API request fails without error handling
  • Throwing errors inside promises without catching
  • Chaining promises without final .catch()

Quick Fix (TL;DR)

Quick Solution
// ❌ Problem - No error handling
fetch('/api/users')
    .then(res => res.json())
    .then(data => console.log(data));

// ✅ Solution 1: Add .catch()
fetch('/api/users')
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));

// ✅ Solution 2: Use async/await with try-catch
async function getUsers() {
    try {
        const res = await fetch('/api/users');
        const data = await res.json();
        console.log(data);
    } catch (error) {
        console.error('Error:', error);
    }
}

Common Scenarios & Solutions

Scenario 1: Missing .catch() on Fetch

The most common case - making API calls without handling potential errors.

Problem
// No error handling - will cause unhandled rejection if API fails
fetch('https://api.example.com/users')
    .then(response => response.json())
    .then(users => {
        console.log(users);
        displayUsers(users);
    });
// If network fails or API returns error, promise is rejected but not caught
Solution
// Solution 1: Add .catch() at the end
fetch('https://api.example.com/users')
    .then(response => response.json())
    .then(users => {
        console.log(users);
        displayUsers(users);
    })
    .catch(error => {
        console.error('Failed to fetch users:', error);
        showErrorMessage('Unable to load users');
    });

// Solution 2: Handle HTTP errors properly
fetch('https://api.example.com/users')
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return response.json();
    })
    .then(users => {
        console.log(users);
        displayUsers(users);
    })
    .catch(error => {
        console.error('Error:', error);
        showErrorMessage(error.message);
    });

Scenario 2: Async/Await Without Try-Catch

Using async/await without try-catch blocks leads to unhandled rejections.

Problem
async function loadUserData() {
    const response = await fetch('/api/user');
    const user = await response.json();
    console.log(user);
}

loadUserData(); // If fetch fails, unhandled rejection!
Solution
// Solution 1: Add try-catch inside function
async function loadUserData() {
    try {
        const response = await fetch('/api/user');
        const user = await response.json();
        console.log(user);
    } catch (error) {
        console.error('Failed to load user:', error);
    }
}

loadUserData();

// Solution 2: Catch when calling the function
async function loadUserData() {
    const response = await fetch('/api/user');
    const user = await response.json();
    return user;
}

loadUserData()
    .then(user => console.log(user))
    .catch(error => console.error('Error:', error));

// Solution 3: Use .catch() on the promise
loadUserData().catch(error => {
    console.error('Error:', error);
});

Scenario 3: Promise Chain Without Final .catch()

Long promise chains need a final .catch() to handle any errors in the chain.

Problem
fetch('/api/user')
    .then(res => res.json())
    .then(user => fetch(`/api/posts/${user.id}`))
    .then(res => res.json())
    .then(posts => {
        console.log(posts);
        displayPosts(posts);
    });
// Any error in this chain is unhandled
Solution
// Add .catch() at the end of the chain
fetch('/api/user')
    .then(res => res.json())
    .then(user => fetch(`/api/posts/${user.id}`))
    .then(res => res.json())
    .then(posts => {
        console.log(posts);
        displayPosts(posts);
    })
    .catch(error => {
        console.error('Error in promise chain:', error);
        showErrorMessage('Failed to load data');
    });

// Or use async/await for cleaner code
async function loadUserPosts() {
    try {
        const userRes = await fetch('/api/user');
        const user = await userRes.json();
        
        const postsRes = await fetch(`/api/posts/${user.id}`);
        const posts = await postsRes.json();
        
        displayPosts(posts);
    } catch (error) {
        console.error('Error:', error);
        showErrorMessage('Failed to load data');
    }
}

loadUserPosts();

Scenario 4: Promise.all() Without Error Handling

When using Promise.all(), if any promise rejects, the entire operation fails.

Problem
Promise.all([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(([users, posts, comments]) => {
    console.log(users, posts, comments);
});
// If any fetch fails, unhandled rejection
Solution
// Solution 1: Add .catch() to Promise.all()
Promise.all([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(([users, posts, comments]) => {
    console.log(users, posts, comments);
})
.catch(error => {
    console.error('Failed to load data:', error);
});

// Solution 2: Use Promise.allSettled() (doesn't reject)
Promise.allSettled([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
])
.then(results => {
    results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
            console.log(`Request ${index} succeeded:`, result.value);
        } else {
            console.error(`Request ${index} failed:`, result.reason);
        }
    });
});

// Solution 3: Catch individual promises
Promise.all([
    fetch('/api/users').catch(err => ({ error: err })),
    fetch('/api/posts').catch(err => ({ error: err })),
    fetch('/api/comments').catch(err => ({ error: err }))
])
.then(results => {
    // Handle results, some may have errors
    console.log(results);
});

Global Error Handlers

Browser (Window)

Global Handler
// Catch all unhandled promise rejections
window.addEventListener('unhandledrejection', event => {
    console.error('Unhandled promise rejection:', event.reason);
    // Log to error tracking service
    // Show user-friendly error message
    event.preventDefault(); // Prevent default browser behavior
});

Node.js

Node.js Handler
process.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason);
    // Log to error tracking service
    // Optionally exit process
    // process.exit(1);
});

Best Practices

  • Always add .catch() - Every promise chain should end with .catch()
  • Use try-catch with async/await - Wrap await calls in try-catch blocks
  • Handle errors at appropriate level - Catch errors where you can handle them meaningfully
  • Use Promise.allSettled() - When you want all promises to complete regardless of failures
  • Add global handlers - Catch any unhandled rejections as a safety net
  • Log errors properly - Use error tracking services like Sentry
  • Show user-friendly messages - Don't expose technical errors to users

Related Errors

Key Takeaways
  • Unhandled promise rejection occurs when promises reject without .catch() handlers
  • Always add .catch() at the end of promise chains
  • Use try-catch blocks with async/await functions
  • Promise.all() rejects if any promise fails - use Promise.allSettled() for partial failures
  • Add global unhandledrejection event listener as safety net
  • Handle errors at the appropriate level where you can respond meaningfully

Frequently Asked Questions


Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.