I am trying to create a Vue error handling component following a similar pattern to the one documented here. It is basically a wrapper that uses the errorCaptured lifecycle hook to detect errors in its child components. If an error is caught, it hides the content passed into its slot and shows an error message instead. Pretty simple. Something like this:
ErrorBoundary.vue
<template>
<div>
<slot v-if="!err"></slot>
<h1 v-else>Oopsy</h1>
</div>
</template>
<script>
export default {
name: 'errorBoundary',
data(){
return {err: false};
},
errorCaptured(err){
this.err = true;
console.log(err);
}
}
</script>
The problem I have is that errorCaptured does not capture errors thrown in its own component's scope. For example, here nothing is caught and logged.
ErrorThrower.vue
<template>
<div>Some content</div>
</template>
<script>
export default {
name: 'errorThrower',
created(){
throw new Error();
},
errorCaptured(err){
console.log(err);
}
}
</script>
If the above example caught the error, then I could add a retry prop to the ErrorBoundary component and accept the content as a slot. Like this:
ErrorThrower.vue
<template>
<ErrorBoundary :onRetry="loadContent">
<div>Some content</div>
</ErrorBoundary>
</template>
<script>
export default {
name: 'errorThrower',
created(){
this.loadContent();
},
methods: {
loadContent(){
// make some call that fails
}
}
}
</script>
Unfortunately this doesn't work, due to the slotted content being on the same scope as the ErrorBoundary component.
Whereas if ErrorThrower is a child compoment, ErrorBoundary will log the error and display a message, because now ErrorThrower's error is caught by errorCaptured.
SomeParent.vue
<template>
<error-boundary>
<error-thrower/>
</error-boundary>
</template>
How can I include a retry button in ErrorBoundary's error message, that will retry some failed async operation if desired? Ideally I want to pass in the callback for the error component to retry on error.