A reusable error boundary component for catching JavaScript errors and displaying fallback UIs.
The ErrorBoundary component is based on React's example component.
Requires Vue3
yarn add vue-error-boundary
npm i vue-error-boundary --save
To use this component simply wrap any other component which may throw an Error. Errors thrown in child components will automatically bubble up to the VErrorBoundary
component.
<VErrorBoundary>
<ImUnstable />
</VErrorBoundary>
If you are using it inside a v-for
, ensure to set the stop-propagation
prop on your VErrorBoundary
component.
<div v-for="...">
<VErrorBoundary stop-propagation>
...
</VErrorBoundary>
</div>
Attribute | Description | Type | Required | Default |
---|---|---|---|---|
fall-back | Fallback component to render in case of error. | Component | false |
DefaultFallback |
on-error | Callback function to perform on error. | Function |
false |
null |
params | Props to pass to your fall back component. | Object |
false |
{} |
stop-propagation | Stop propagation of errors to other errorCaptured hooks. |
boolean |
false |
false |
Property | Description | Type |
---|---|---|
error | The error | Error |
hasError | Whether an error occurred. | boolean |
info | Information on where the error was captured | string |
We can provide a fallback UI to display via the fall-back
prop. It simply takes a Vue component to render.
<template>
<VErrorBoundary :fall-back="productError">
<ProductCard ... />
</VErrorBoundary>
</template>
<script>
import ProductErrorCard from '...'
export default {
// ...
data () {
return {
productError: ProductErrorCard
}
}
}
</script>
You can pass props to your fallback component through the params
prop. params
expects an object containing the data you wish to pass.
<template>
<ul class="contact-list">
<template v-for="contact in contacts">
<VErrorBoundary :key="contact.id"
:fall-back="fallBack"
:params="{ id: contact.id }">
<app-contact :contact="contact" />
</VErrorBoundary>
</template>
</ul>
</template>
<script>
import MyCustomFallbackComponent from '...'
export default {
data: () => ({
fallBack: MyCustomFallbackComponent,
contacts: [...]
})
}
</script>
Then in your custom fallback component:
<template>
<div>
Could not render - {{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
}
</script>
Furthermore, we can directly access the contents of the VErrorBoundary
component's errorCaptured
hook either through a callback or Vue's emit.
If you do not wish to use a fallback component you can alternatively utilize scoped slots to present data in your current template.
<VErrorBoundary>
<template #boundary="{ hasError }">
<div v-if="!hasError">No error occurred.</div>
<div v-else>Message to appear if error occurred.</div>
</template>
</VErrorBoundary>
The VErrorBoundary
can receive a callback function through the on-error
prop.
<template>
<VErrorBoundary :on-error="handleError">...</VErrorBoundary>
<template>
<script>
// ...
methods: {
handleError (err, vm, info) {
// do something
}
}
// ...
</script>
The callback function will receive the same parameters as the errorCaptured
method.
We can also listen to a Vue event via an errorCaptured
event.
<template>
<VErrorBoundary @error-captured="handleError">...</VErrorBoundary>
</template>
<script>
// ...
methods: {
handleError (err, vm, info) {
// do something
}
}
// ...
</script>
The errorCaptured
hook will continue to propagate errors up the component tree unless it returns false
. Doing so will stop any additional errorCaptured
hooks to execute and the global errorHandler
from being invoked for the error. To do this we can use the stop-propagation
prop.
<VErrorBoundary stop-propagation>
...
</VErrorBoundary>