Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/suspense-no-builtin-error-handling.md
1# Suspense Has No Built-in Error Handling23## Rule45`<Suspense>` does not provide error handling via the component itself. You must implement error handling using `errorCaptured` option or `onErrorCaptured()` hook in a parent component to catch async errors.67## Why This Matters89Without explicit error handling, async errors in suspended components will propagate uncaught, potentially crashing the application or leaving users stuck on loading states. Unlike React's Error Boundaries, Vue's Suspense requires manual error boundary implementation.1011## Bad Code1213```vue14<script setup>15// No error handling - async errors will propagate uncaught16</script>1718<template>19<Suspense>20<AsyncComponent />21<template #fallback>22Loading...23</template>24</Suspense>25</template>26```2728## Good Code2930```vue31<script setup>32import { ref, onErrorCaptured } from 'vue'33import AsyncComponent from './AsyncComponent.vue'3435const error = ref(null)3637onErrorCaptured((err) => {38error.value = err39return false // Prevent error from propagating further40})41</script>4243<template>44<div v-if="error" class="error-state">45<p>Something went wrong: {{ error.message }}</p>46<button @click="error = null">Retry</button>47</div>4849<Suspense v-else>50<AsyncComponent />51<template #fallback>52Loading...53</template>54</Suspense>55</template>56```5758## Reusable Error Boundary Pattern5960```vue61<!-- ErrorBoundary.vue -->62<script setup>63import { ref, onErrorCaptured } from 'vue'6465const props = defineProps({66fallback: {67type: String,68default: 'Something went wrong'69}70})7172const emit = defineEmits(['error'])7374const error = ref(null)7576onErrorCaptured((err, instance, info) => {77error.value = { err, instance, info }78emit('error', { err, instance, info })79return false80})8182const reset = () => {83error.value = null84}8586defineExpose({ reset })87</script>8889<template>90<slot v-if="!error" />91<slot v-else name="error" :error="error" :reset="reset">92<div class="error-boundary">93{{ fallback }}94<button @click="reset">Retry</button>95</div>96</slot>97</template>98```99100```vue101<!-- Usage -->102<template>103<ErrorBoundary @error="logError">104<Suspense>105<AsyncDashboard />106<template #fallback>Loading dashboard...</template>107</Suspense>108109<template #error="{ error, reset }">110<DashboardError :error="error" @retry="reset" />111</template>112</ErrorBoundary>113</template>114```115116## Key Points1171181. Always wrap `<Suspense>` with error handling logic in production1192. Use `onErrorCaptured` for Composition API or `errorCaptured` option for Options API1203. Return `false` from the error handler to stop propagation1214. Consider creating a reusable `ErrorBoundary` component to reduce boilerplate1225. Provide a way for users to retry failed operations123124## References125126- [Vue.js Suspense Documentation](https://vuejs.org/guide/built-ins/suspense#error-handling)127- [Vue.js onErrorCaptured](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured)128