JAVASCRIPT
Vue 3 Error Boundary Component with onErrorCaptured
Create resilient Vue 3 applications by implementing error boundaries using the 'onErrorCaptured' hook to gracefully handle and display errors from child components.
// components/ErrorBoundary.vue
<template>
<div class="error-boundary">
<template v-if="error">
<div class="error-message-box">
<h3>Something went wrong!</h3>
<p>{{ error.message }}</p>
<button @click="resetError">Try Again</button>
</div>
</template>
<template v-else>
<slot></slot>
</template>
</div>
</template>
<script setup>
import { ref, onErrorCaptured } from 'vue';
const error = ref(null);
// onErrorCaptured captures errors from descendants
onErrorCaptured((err, instance, info) => {
error.value = err;
console.error('Error caught by ErrorBoundary:', err, instance, info);
// Return false to stop the error from propagating further up the component tree
// Return true to allow it to propagate (useful for multiple error boundaries)
return true;
});
const resetError = () => {
error.value = null;
};
</script>
<style scoped>
.error-boundary {
border: 2px dashed #ff6b6b;
padding: 20px;
margin: 10px 0;
background-color: #fffafa;
border-radius: 8px;
}
.error-message-box {
text-align: center;
color: #c0392b;
}
.error-message-box h3 {
color: #e74c3c;
}
.error-message-box p {
font-size: 0.9em;
margin-bottom: 15px;
}
.error-message-box button {
background-color: #e74c3c;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
}
</style>
// components/BuggyComponent.vue (example component that throws an error)
<template>
<div class="buggy-component">
<h3>Buggy Component</h3>
<button @click="throwError">Cause Error</button>
<p>This component will throw an error when the button is clicked.</p>
</div>
</template>
<script setup>
function throwError() {
throw new Error('I am a deliberately buggy error!');
}
</script>
<style scoped>
.buggy-component {
border: 1px solid #ccc;
padding: 15px;
margin-top: 10px;
background-color: #f0f0f0;
border-radius: 5px;
}
.buggy-component button {
background-color: #f39c12;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
}
</style>
// App.vue (example usage)
<template>
<div>
<h1>Vue 3 Error Boundary Example</h1>
<ErrorBoundary>
<p>This content is inside the error boundary.</p>
<BuggyComponent />
</ErrorBoundary>
<p style="margin-top: 30px;">This content is outside the error boundary and will not be affected.</p>
</div>
</template>
<script setup>
import ErrorBoundary from './components/ErrorBoundary.vue';
import BuggyComponent from './components/BuggyComponent.vue';
</script>
How it works: This snippet demonstrates creating an Error Boundary component in Vue 3 using `onErrorCaptured`. This lifecycle hook catches errors originating from descendant components within the boundary's slot. When an error occurs, it's stored in a `ref` and a fallback UI is rendered, preventing the entire application from crashing. The `resetError` function allows the user to clear the error and potentially re-render the child components. This provides a robust way to handle unexpected runtime errors gracefully.