window.onerror and the unhandledrejection event form a safety net for errors that slip past every try/catch — the last line of defense used by production error-monitoring tools like Sentry.
1Global Error Handling | JavaScript Tutorial - In-Depth Guide Part 1
The window 'error' event fires whenever an uncaught exception propagates all the way up without being caught by any try/catch.
window.addEventListener('error', (event) => {
console.log('Uncaught error:', event.message, event.filename, event.lineno);
reportToErrorService(event.error);
});The Global error Event
2Global Error Handling | JavaScript Tutorial - In-Depth Guide Part 2
The 'unhandledrejection' event fires when a Promise rejects and nothing ever calls .catch() (or an equivalent) on it before it's garbage collected.
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled rejection:', event.reason);
reportToErrorService(event.reason);
});unhandledrejection
3Global Error Handling | JavaScript Tutorial - In-Depth Guide Part 3
Calling event.preventDefault() inside an unhandledrejection handler suppresses the default browser console warning, useful once you're confident your own reporting has captured it.
window.addEventListener('unhandledrejection', (event) => {
reportToErrorService(event.reason);
event.preventDefault(); // suppress default browser console warning
});Suppressing Default Warnings
4Global Error Handling | JavaScript Tutorial - In-Depth Guide Part 4
Global handlers are a safety net, not a substitute for proper try/catch and .catch() usage at the source of an operation — by the time an error reaches here, you've lost the specific context needed to recover gracefully.
// Better: handle it locally where you have context
try {
saveUserProfile(data);
} catch (err) {
showFieldError(err); // specific, actionable
}
// Global handler is the fallback for everything elseA Safety Net, Not a Strategy
5Global Error Handling | JavaScript Tutorial - In-Depth Guide Part 5
In Node.js, the equivalent mechanisms are process.on('uncaughtException') and process.on('unhandledRejection') — conceptually identical, but the recommended practice there is usually to log and then exit, since process state may be corrupted.
process.on('uncaughtException', (err) => {
logger.fatal(err);
process.exit(1); // don't keep running in a possibly-corrupted state
});The Node.js Equivalent
6Step-by-Step Breakdown
The window 'error' event fires whenever an uncaught exception propagates all the way up without being caught by any try/catch.
The 'unhandledrejection' event fires when a Promise rejects and nothing ever calls .catch() (or an equivalent) on it before it's garbage collected.
Checkpoint: Does the "unhandledrejection" event fire for a Promise rejection that IS handled with a .catch()?
- →Yes, it always fires for every rejection
- →No, only for rejections nobody ever handles
Calling event.preventDefault() inside an unhandledrejection handler suppresses the default browser console warning, useful once you're confident your own reporting has captured it.
Global handlers are a safety net, not a substitute for proper try/catch and .catch() usage at the source of an operation — by the time an error reaches here, you've lost the specific context needed to recover gracefully.
Checkpoint: Should global error handlers replace using try/catch at the specific point where an error can occur?
- →Yes, one global handler is sufficient for an entire app
- →No, they are a fallback safety net, not a primary error-handling strategy
In Node.js, the equivalent mechanisms are process.on('uncaughtException') and process.on('unhandledRejection') — conceptually identical, but the recommended practice there is usually to log and then exit, since process state may be corrupted.
Next, we'll explore 'Promise Error Handling Patterns'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Global Handlers Shouldn't Be the Only Path to User-Facing Error Feedback
While a global error handler is valuable for developer-facing reporting, it typically cannot construct a meaningful, context-aware accessible error message for the user — local error handling remains necessary to give screen reader users a clear, actionable explanation of what went wrong and how to proceed.
SEO Implications
- 1
Production Error Visibility Helps Prevent Silent Content-Breaking Bugs
Catching previously-invisible runtime errors via global handlers can surface bugs that silently break page functionality or rendering for a subset of users/browsers, which might otherwise degrade the experience search engines and users encounter without anyone noticing.
Best Practices
Wire Global Handlers to an Error-Reporting Service in Production
This is the only reliable way to learn about real-world failures your test suite and manual testing never encountered, since users rarely file bug reports for silent errors.
Treat Global Handlers as a Safety Net, Not a Replacement for Local Error Handling
Handle errors as close to their source as possible (with context-specific recovery), and rely on global handlers only to catch and report whatever slips through.
Frequent Bugs
Forgetting to attach a .catch() to a fire-and-forget async call, causing a silent unhandled rejection that never surfaces anywhere without a global unhandledrejection listener in place.
Set up a global unhandledrejection listener early in the app's lifecycle to catch and report these, in addition to fixing the missing .catch() at the source once identified.
In Node.js, catching uncaughtException and then continuing normal operation as if nothing happened, risking further corruption from an already-inconsistent process state.
Log the error thoroughly, perform any necessary cleanup, and exit the process deliberately rather than attempting to keep it running indefinitely after an uncaught exception.
Real-World Examples
A Minimal Client-Side Error Reporting Pipeline
A small app needed basic production error visibility without integrating a full third-party error-monitoring service.
window.addEventListener('error', (e) => {
sendBeacon('/api/log-error', { message: e.message, stack: e.error?.stack });
});
window.addEventListener('unhandledrejection', (e) => {
sendBeacon('/api/log-error', { message: String(e.reason), stack: e.reason?.stack });
});