diff --git a/apps/stage-web/src/App.vue b/apps/stage-web/src/App.vue index ac5cecf72..7c5b82ae8 100644 --- a/apps/stage-web/src/App.vue +++ b/apps/stage-web/src/App.vue @@ -10,7 +10,7 @@ import { useContextBridgeStore } from '@proj-airi/stage-ui/stores/mods/api/conte import { useAiriCardStore } from '@proj-airi/stage-ui/stores/modules/airi-card' import { useOnboardingStore } from '@proj-airi/stage-ui/stores/onboarding' import { useSettings, useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings' -import { useTheme } from '@proj-airi/ui' +import { ErrorBoundary, useTheme } from '@proj-airi/ui' import { StageTransitionGroup } from '@proj-airi/ui-transitions' import { storeToRefs } from 'pinia' import { computed, onMounted, onUnmounted, watch } from 'vue' @@ -128,7 +128,12 @@ function handleSetupSkipped() { :use-page-specific-transitions="settings.usePageSpecificTransitions.value" > - + + + diff --git a/docs/ai/context/ui-components.md b/docs/ai/context/ui-components.md index 1e28f627f..69b1c6007 100644 --- a/docs/ai/context/ui-components.md +++ b/docs/ai/context/ui-components.md @@ -126,6 +126,20 @@ Error display with copy/feedback buttons and scrollable stack trace. **Emits**: `copy(content: string)`, `feedback()` +### ErrorBoundary + +Catches synchronous render/setup errors in descendants via `onErrorCaptured` and renders a fallback (built-in `ContainerError` + retry button) instead of letting the error propagate. Use to wrap `` or any subtree where partial failure should not blank the host layout. Async/unhandled rejections are NOT captured — use `app.config.errorHandler` for those. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `title` | `string?` | — | Optional title shown above error details | +| `retryable` | `boolean?` | `true` | Show built-in retry button | +| `retryLabel` | `string?` | `'Try again'` | Retry button label | + +**Slots**: `default`, `fallback({ error, info, retry })` +**Emits**: `error(err, instance, info)`, `retry()` +**Exposed**: `retry()`, `hasError()` + ### DoubleCheckButton Two-stage confirmation button — click once to reveal confirm/cancel. diff --git a/packages/ui/src/components/misc/error-boundary.vue b/packages/ui/src/components/misc/error-boundary.vue new file mode 100644 index 000000000..785a9d113 --- /dev/null +++ b/packages/ui/src/components/misc/error-boundary.vue @@ -0,0 +1,117 @@ + + + diff --git a/packages/ui/src/components/misc/index.ts b/packages/ui/src/components/misc/index.ts index 62b549c37..31fb96590 100644 --- a/packages/ui/src/components/misc/index.ts +++ b/packages/ui/src/components/misc/index.ts @@ -2,4 +2,5 @@ export { default as Button } from './button.vue' export { default as Callout } from './callout.vue' export { default as ContainerError } from './container-error.vue' export { default as DoubleCheckButton } from './double-check-button.vue' +export { default as ErrorBoundary } from './error-boundary.vue' export { default as Progress } from './progress.vue'