0 day streak
javascript / intermediate
Snippet

Catching Component Hierarchy Failures with the onErrorCaptured Hook

Vue's `onErrorCaptured` lifecycle hook intercepts errors propagating from any descendant component tree. By inspecting the error instance and returning `false`, the boundary component halts further error propagation, allowing the application to render fallback UI scoped strictly to the failing subtree.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { ref, onErrorCaptured, defineComponent, h } from 'vue';
export const ErrorBoundary = defineComponent({
name: 'ErrorBoundary',
setup(_, { slots }) {
const activeError = ref(null);
const errorInfo = ref('');
onErrorCaptured((err, instance, info) => {
activeError.value = err instanceof Error ? err : new Error(String(err));
errorInfo.value = info;
// Return false to prevent the error from bubbling up to parent handlers
return false;
});
const resetError = () => {
activeError.value = null;
errorInfo.value = '';
};
return () => {
if (activeError.value) {
return slots.fallback?.({
error: activeError.value,
info: errorInfo.value,
reset: resetError
}) ?? h('div', { class: 'error-banner' }, activeError.value.message);
}
return slots.default?.();
};
}
});
vue
Breakdown
1
onErrorCaptured((err, instance, info) => {
Registers a handler that triggers whenever a child component throws during rendering, computed properties, or watchers.
2
activeError.value = err instanceof Error ? err : new Error(String(err));
Normalizes arbitrary thrown values into standard JavaScript Error instances.
3
return false;
Stops the error from propagating further up to the root Vue error handler or browser console.
4
return slots.fallback?.({ ... }) ?? h('div', ...);
Conditionally renders the scoped fallback slot when an error is present, or the default slot otherwise.