I am making a render library for my project with Vue 3 + Vite.
Basically I have a json array of products
which I pass to special <Render :products />
component.
This Render
component reads all json products and converts them into Vue components:
// Render.vue
<script setup lang="ts">
import { Product } from 'bitran';
import { resolveComponent } from 'vue';
const props = defineProps<{ products: Product[] }>();
const products = props.products;
</script>
<template>
<template v-for="product in products">
<component :is="resolveComponent(product.type)" :product />
</template>
</template>
Of course errors can occur when rendering json data to component.
How can I catch these errors during rendering <component ... />
and replace them with my own custom <Error :msg />
component so the rendering process won’t stop and the end-user could see, which product caused the problem and why?
For example, I intentionally throw an Error inside my <Paragraph>
component and would like this <Paragraph>
component to be converted into <Error>
component instead:
// Paragraph.vue
<script setup lang="ts">
import { Paragraph } from 'bitran';
import { getProductAttrs, useProduct } from '@lib/content/util';
import Render from '@lib/Render.vue';
const block = useProduct<Paragraph>();
throw new Error('This message should be passed to <Error> component!'); // Error here
</script>
<template>
<p v-bind="getProductAttrs(block)">
<Render :products="block.content" />
</p>
</template>
2
Answers
You can use the
onErrorCaptured
hook to capture the error and the component instance, and get its content and show it, then return false in order to not break the app, the second parameter in the hook callback represents the component instance that’s causing the error :TryRender.vue
Note that you should give the component an explicit name using the
defineOptions
macro :If you want to catch errors in
setup()
you could overwrite it and add error handling:VUE SFC PLAYGROUND