How to create a global Promise Rejection Handler in JavaScript?

Promise rejection handlers are a powerful tool in JavaScript for handling errors that occur in asynchronous code. In this article, we will learn how to build a global promise rejection handler in JavaScript and how it can help your application manage errors effectively. You can detect unhandled promise rejections using the global unhandledrejection event and take necessary action, such as logging errors to an error tracking service or displaying user notifications.

A more understandable syntax for handling promise rejection is provided by async-await error handling, but it requires wrapping each async function in a try-catch block. Combining async-await with a global promise rejection handler can provide your application with a robust and reliable error handling system.

What are Promise Rejections?

Promises in JavaScript are a way to handle asynchronous code, such as fetching data from a server or waiting for user input. A promise is an object that represents a value that may not yet be available. Promises have three states:

  • Pending - The initial state, neither fulfilled nor rejected
  • Fulfilled - The operation completed successfully
  • Rejected - The operation failed

When a promise is rejected, it will trigger a rejection handler if one is attached to the promise. This allows you to handle the error and take appropriate action. However, if no rejection handler is attached to the promise, the error will go unnoticed and can lead to bugs in your application.

Creating a Global Promise Rejection Handler

JavaScript provides a global unhandledrejection event that can be used to catch unhandled promise rejections. This event is triggered when a promise is rejected and no rejection handler is attached to the promise.

Basic Example

<html>
<body>
    <div id="error-message"></div>
    <script>
        window.addEventListener("unhandledrejection", event => {
            console.log("Unhandled rejection:", event.reason);
            document.getElementById("error-message").innerHTML = 
                "Error: " + event.reason.message;
        });
        
        // Create a promise that intentionally rejects without handling
        const myPromise = new Promise((resolve, reject) => {
            setTimeout(() => {
                reject(new Error("Something went wrong!"));
            }, 1000);
        });
        
        // This promise rejection is unhandled, so it triggers the global handler
    </script>
</body>
</html>

This code attaches an event listener to the global unhandledrejection event, which triggers when a promise is rejected without a rejection handler. The event object contains a reason property that holds the rejection reason.

Comprehensive Error Handling Example

<html>
<body>
    <div id="error-log"></div>
    <div id="error-message"></div>
    <button onclick="triggerError()">Trigger Unhandled Error</button>
    
    <script>
        window.addEventListener("unhandledrejection", event => {
            logErrorToService(event.reason);
            displayErrorMessage(event.reason);
            // Prevent the default browser behavior
            event.preventDefault();
        });
        
        function logErrorToService(error) {
            // Simulate logging to an error tracking service
            const errorLog = document.getElementById("error-log");
            errorLog.innerHTML = "Logged: " + error.message;
            console.log("Error logged to service:", error);
        }
        
        function displayErrorMessage(error) {
            // Display user-friendly error message
            const errorMessage = document.getElementById("error-message");
            errorMessage.innerHTML = "?? " + error.message;
        }
        
        function triggerError() {
            // Create an unhandled promise rejection
            Promise.reject(new Error("Unhandled promise rejection triggered!"));
        }
    </script>
</body>
</html>

This example demonstrates catching the unhandledrejection event and routing the error to two functions: one for logging to an error tracking service and another for displaying user notifications.

Error Handling with Async-Await

Async-await provides a cleaner syntax for working with promises. You can handle errors using standard try-catch blocks when using async-await.

Try-Catch with Async-Await

<html>
<body>
    <button onclick="fetchData()">Fetch Data</button>
    <div id="data-display"></div>
    <div id="error-display"></div>
    
    <script>
        async function fetchData() {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                
                const data = await response.json();
                document.getElementById("data-display").innerHTML = 
                    "<h3>Data:</h3><pre>" + JSON.stringify(data, null, 2) + "</pre>";
                document.getElementById("error-display").innerHTML = "";
            } catch (error) {
                document.getElementById("error-display").innerHTML = 
                    "<p style='color: red;'>Error: " + error.message + "</p>";
                document.getElementById("data-display").innerHTML = "";
            }
        }
    </script>
</body>
</html>

The async function fetchData uses the await keyword to wait for the promise returned by the fetch method to resolve. Any errors that occur in the try block will be caught by the catch block.

Combining Global Handler with Local Error Handling

While try-catch blocks provide local error handling, combining them with a global promise rejection handler creates a comprehensive error handling strategy:

// Global handler for unhandled rejections
window.addEventListener("unhandledrejection", event => {
    console.error("Unhandled promise rejection:", event.reason);
    // Log to error tracking service
    logErrorToService(event.reason);
    // Prevent default browser behavior
    event.preventDefault();
});

// Local error handling with try-catch
async function processData() {
    try {
        const result = await someAsyncOperation();
        return result;
    } catch (error) {
        console.error("Handled error:", error);
        throw error; // Re-throw if needed
    }
}

Best Practices

  • Always call event.preventDefault() in the global handler to prevent browser default behavior
  • Use the global handler as a safety net, not a replacement for proper error handling
  • Log errors appropriately for debugging and monitoring
  • Provide user-friendly error messages when appropriate

Conclusion

Global promise rejection handlers provide a safety net for unhandled promise rejections in JavaScript applications. When combined with proper try-catch error handling in async functions, they create a robust error management system that improves both user experience and application reliability.

Updated on: 2026-03-15T23:19:00+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements