JAVASCRIPT
Implement Centralized Error Handling in Vue 3
Set up robust global error handling in your Vue 3 application using `app.config.errorHandler` and `onErrorCaptured` to catch and manage runtime errors effectively.
// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// Global error handler for all component errors
app.config.errorHandler = (err, instance, info) => {
// `err`: The error object caught
// `instance`: The component instance where the error originated
// `info`: A string describing the error source (e.g. 'render function', 'hook:mounted')
console.error('--- Global Error Caught ---');
console.error('Error:', err.message);
console.error('Component Info:', info);
// You can send this error to an external logging service here
// e.g., Sentry.captureException(err, { extra: { instance, info } });
};
// Global error handler for unhandled promise rejections
window.addEventListener('unhandledrejection', (event) => {
console.error('--- Unhandled Promise Rejection ---');
console.error('Reason:', event.reason);
event.preventDefault(); // Prevent default browser behavior (e.g., logging to console twice)
});
// Global error handler for general runtime errors outside Vue's scope
window.onerror = (message, source, lineno, colno, error) => {
console.error('--- Window Error Caught ---');
console.error('Message:', message);
console.error('Source:', source, 'Line:', lineno, 'Col:', colno);
console.error('Error Object:', error);
return true; // Return true to prevent default browser error handling
};
app.mount('#app');
// ErrorProneComponent.vue
<template>
<div>
<h2>Error Prone Component</h2>
<button @click="throwSyncError">Throw Sync Error</button>
<button @click="throwAsyncError">Throw Async Error (setTimeout)</button>
<button @click="throwPromiseRejection">Throw Promise Rejection</button>
<p v-if="componentError" style="color: red;">Component specific error: {{ componentError }}</p>
</div>
</template>
<script setup>
import { ref, onErrorCaptured } from 'vue';
const componentError = ref(null);
const throwSyncError = () => {
throw new Error('This is a synchronous error from a button click!');
};
const throwAsyncError = () => {
setTimeout(() => {
throw new Error('This is an async error inside setTimeout!');
}, 0);
};
const throwPromiseRejection = () => {
Promise.reject('An unhandled promise rejection occurred!');
};
// Component-level error handler
onErrorCaptured((err, instance, info) => {
console.error('--- Component Error Captured ---');
console.error('Caught in component:', err.message);
componentError.value = err.message;
// Return `false` to stop the error from propagating further up to the global handler.
// Return `true` (or nothing) to let it propagate to the global handler as well.
return true;
});
</script>
How it works: Robust applications require comprehensive error handling. This snippet demonstrates how to implement centralized error management in Vue 3. `app.config.errorHandler` catches errors originating from Vue components, including lifecycle hooks and watch functions, providing a global fallback. Additionally, `window.onerror` handles general runtime errors, and `window.addEventListener('unhandledrejection')` catches promise rejections. For component-specific error handling, `onErrorCaptured` allows components to gracefully handle errors within their own subtree, potentially preventing them from propagating globally.