Skip to content

Commit 4edb14c

Browse files
fix(nuxt): wait for suspense to resolve before handling NuxtErrorBoundary error (#31791)
1 parent b943fc3 commit 4edb14c

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

packages/nuxt/src/app/components/nuxt-error-boundary.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineComponent, onErrorCaptured, ref } from 'vue'
22
import { useNuxtApp } from '../nuxt'
3+
import { onNuxtReady } from '../composables/ready'
34

45
export default defineComponent({
56
name: 'NuxtErrorBoundary',
@@ -11,16 +12,27 @@ export default defineComponent({
1112
},
1213
setup (_props, { slots, emit }) {
1314
const error = ref<Error | null>(null)
14-
const nuxtApp = useNuxtApp()
1515

1616
if (import.meta.client) {
17-
onErrorCaptured((err, target, info) => {
18-
if (!nuxtApp.isHydrating || !nuxtApp.payload.serverRendered) {
19-
emit('error', err)
20-
nuxtApp.hooks.callHook('vue:error', err, target, info)
21-
error.value = err
22-
return false
17+
const nuxtApp = useNuxtApp()
18+
19+
function handleError (...args: Parameters<Parameters<typeof onErrorCaptured>[0]>) {
20+
const [err, instance, info] = args
21+
emit('error', err)
22+
23+
nuxtApp.hooks.callHook('vue:error', err, instance, info)
24+
25+
error.value = err as Error
26+
}
27+
28+
onErrorCaptured((err, instance, info) => {
29+
if (!nuxtApp.isHydrating) {
30+
handleError(err, instance, info)
31+
} else {
32+
onNuxtReady(() => handleError(err, instance, info))
2333
}
34+
35+
return false
2436
})
2537
}
2638

test/basic.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,14 @@ describe('errors', () => {
12411241

12421242
await page.close()
12431243
})
1244+
1245+
it('should allow catching errors within error boundaries', async () => {
1246+
const { page } = await renderPage('/error/error-boundary')
1247+
await page.getByText('This is the error rendering')
1248+
await page.close()
1249+
1250+
await expectNoClientErrors('/error/error-boundary')
1251+
})
12441252
})
12451253

12461254
describe('navigate external', () => {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<template>
2+
<div>
3+
<NuxtErrorBoundary>
4+
<template #default>
5+
<MyBrokenComponent />
6+
</template>
7+
<template #error>
8+
<p>This is the error rendering</p>
9+
</template>
10+
</NuxtErrorBoundary>
11+
</div>
12+
</template>
13+
14+
<script setup lang="ts">
15+
const MyBrokenComponent = defineComponent({
16+
setup () {
17+
onMounted(() => {
18+
throw new Error('This is broken')
19+
})
20+
21+
return () => h('div', 'This is a broken component')
22+
},
23+
})
24+
</script>

0 commit comments

Comments
 (0)