fix(nuxt): wrap caught asyncData error in createError (#24093)

Co-authored-by: Bogdan Kostyuk <contact@bogdankostyuk.xyz>
This commit is contained in:
Damian Głowala 2023-11-08 14:28:52 +01:00 committed by GitHub
parent dd6cc9e431
commit 61dd849aa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 7 deletions

View File

@ -204,6 +204,9 @@ export function useAsyncData<
if (options.pick) { if (options.pick) {
result = pick(result as any, options.pick) as DataT result = pick(result as any, options.pick) as DataT
} }
nuxt.payload.data[key] = result
asyncData.data.value = result asyncData.data.value = result
asyncData.error.value = null asyncData.error.value = null
asyncData.status.value = 'success' asyncData.status.value = 'success'
@ -212,7 +215,7 @@ export function useAsyncData<
// If this request is cancelled, resolve to the latest request. // If this request is cancelled, resolve to the latest request.
if ((promise as any).cancelled) { return nuxt._asyncDataPromises[key] } if ((promise as any).cancelled) { return nuxt._asyncDataPromises[key] }
asyncData.error.value = error asyncData.error.value = createError(error) as DataE
asyncData.data.value = unref(options.default!()) asyncData.data.value = unref(options.default!())
asyncData.status.value = 'error' asyncData.status.value = 'error'
}) })
@ -220,11 +223,7 @@ export function useAsyncData<
if ((promise as any).cancelled) { return } if ((promise as any).cancelled) { return }
asyncData.pending.value = false asyncData.pending.value = false
nuxt.payload.data[key] = asyncData.data.value
if (asyncData.error.value) {
// We use `createError` and its .toJSON() property to normalize the error
nuxt.payload._errors[key] = createError(asyncData.error.value)
}
delete nuxt._asyncDataPromises[key] delete nuxt._asyncDataPromises[key]
}) })
nuxt._asyncDataPromises[key] = promise nuxt._asyncDataPromises[key] = promise

View File

@ -128,10 +128,20 @@ describe('useAsyncData', () => {
}) })
it('should capture errors', async () => { it('should capture errors', async () => {
const { error, status, pending } = await useAsyncData(() => Promise.reject(new Error('test'))) const { data, error, status, pending } = await useAsyncData('error-test', () => Promise.reject(new Error('test')), { default: () => 'default' })
expect(data.value).toMatchInlineSnapshot('"default"')
expect(error.value).toMatchInlineSnapshot('[Error: test]') expect(error.value).toMatchInlineSnapshot('[Error: test]')
expect(status.value).toBe('error') expect(status.value).toBe('error')
expect(pending.value).toBe(false) expect(pending.value).toBe(false)
expect(useNuxtApp().payload._errors['error-test']).toMatchInlineSnapshot('[Error: test]')
// TODO: fix the below
// const { data: syncedData, error: syncedError, status: syncedStatus, pending: syncedPending } = await useAsyncData('error-test', () => ({}), { immediate: false })
// expect(syncedData.value).toEqual(null)
// expect(syncedError.value).toEqual(error.value)
// expect(syncedStatus.value).toEqual('idle')
// expect(syncedPending.value).toEqual(true)
}) })
// https://github.com/nuxt/nuxt/issues/23411 // https://github.com/nuxt/nuxt/issues/23411
@ -182,6 +192,22 @@ describe('useAsyncData', () => {
} }
`) `)
}) })
it('should use default while pending', async () => {
const promise = useAsyncData(() => Promise.resolve('test'), { default: () => 'default' })
const { data, pending } = promise
expect(pending.value).toBe(true)
expect(data.value).toMatchInlineSnapshot('"default"')
await promise
expect(data.value).toMatchInlineSnapshot('"test"')
})
it('should use default after reject', async () => {
const { data } = await useAsyncData(() => Promise.reject(new Error('test')), { default: () => 'default' })
expect(data.value).toMatchInlineSnapshot('"default"')
})
}) })
describe('errors', () => { describe('errors', () => {