diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 24acd18f5bd..2a1446dd15a 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -1,6 +1,7 @@ import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref } from 'vue' import type { Ref, WatchSource } from 'vue' import { NuxtApp, useNuxtApp } from '../nuxt' +import { createError } from './error' export type _Transform = (input: Input) => Output @@ -61,7 +62,7 @@ export function useAsyncData< > ( handler: (ctx?: NuxtApp) => Promise, options?: AsyncDataOptions -): AsyncData, PickKeys>, DataE | null | true> +): AsyncData, PickKeys>, DataE | null> export function useAsyncData< DataT, DataE = Error, @@ -71,13 +72,13 @@ export function useAsyncData< key: string, handler: (ctx?: NuxtApp) => Promise, options?: AsyncDataOptions -): AsyncData, PickKeys>, DataE | null | true> +): AsyncData, PickKeys>, DataE | null> export function useAsyncData< DataT, DataE = Error, Transform extends _Transform = _Transform, PickKeys extends KeyOfRes = KeyOfRes -> (...args: any[]): AsyncData, PickKeys>, DataE | null | true> { +> (...args: any[]): AsyncData, PickKeys>, DataE | null> { const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined if (typeof args[0] !== 'string') { args.unshift(autoKey) } @@ -114,7 +115,7 @@ export function useAsyncData< nuxt._asyncData[key] = { data: ref(useInitialCache() ? nuxt.payload.data[key] : options.default?.() ?? null), pending: ref(!useInitialCache()), - error: ref(nuxt.payload._errors[key] ?? null) + error: ref(nuxt.payload._errors[key] ? createError(nuxt.payload._errors[key]) : null) } } // TODO: Else, Soemhow check for confliciting keys with different defaults or fetcher @@ -168,7 +169,8 @@ export function useAsyncData< asyncData.pending.value = false nuxt.payload.data[key] = asyncData.data.value if (asyncData.error.value) { - nuxt.payload._errors[key] = true + // We use `createError` and its .toJSON() property to normalize the error + nuxt.payload._errors[key] = createError(asyncData.error.value) } delete nuxt._asyncDataPromises[key] }) @@ -240,7 +242,7 @@ export function useLazyAsyncData< > ( handler: (ctx?: NuxtApp) => Promise, options?: Omit, 'lazy'> -): AsyncData, PickKeys>, DataE | null | true> +): AsyncData, PickKeys>, DataE | null> export function useLazyAsyncData< DataT, DataE = Error, @@ -250,13 +252,13 @@ export function useLazyAsyncData< key: string, handler: (ctx?: NuxtApp) => Promise, options?: Omit, 'lazy'> -): AsyncData, PickKeys>, DataE | null | true> +): AsyncData, PickKeys>, DataE | null> export function useLazyAsyncData< DataT, DataE = Error, Transform extends _Transform = _Transform, PickKeys extends KeyOfRes = KeyOfRes -> (...args: any[]): AsyncData, PickKeys>, DataE | null | true> { +> (...args: any[]): AsyncData, PickKeys>, DataE | null> { const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined if (typeof args[0] !== 'string') { args.unshift(autoKey) } const [key, handler, options] = args as [string, (ctx?: NuxtApp) => Promise, AsyncDataOptions] diff --git a/packages/nuxt/src/app/composables/fetch.ts b/packages/nuxt/src/app/composables/fetch.ts index bf23534ca7c..d55d7e98dce 100644 --- a/packages/nuxt/src/app/composables/fetch.ts +++ b/packages/nuxt/src/app/composables/fetch.ts @@ -30,7 +30,7 @@ export function useFetch< > ( request: Ref | ReqT | (() => ReqT), opts?: UseFetchOptions<_ResT, Transform, PickKeys> -): AsyncData, PickKeys>, ErrorT | null | true> +): AsyncData, PickKeys>, ErrorT | null> export function useFetch< ResT = void, ErrorT = FetchError, @@ -114,7 +114,7 @@ export function useLazyFetch< > ( request: Ref | ReqT | (() => ReqT), opts?: Omit, 'lazy'> -): AsyncData, PickKeys>, ErrorT | null | true> +): AsyncData, PickKeys>, ErrorT | null> export function useLazyFetch< ResT = void, ErrorT = FetchError, diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic/types.ts index 0fc4e363719..40b90b012e4 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic/types.ts @@ -28,8 +28,8 @@ describe('API routes', () => { expectTypeOf(useAsyncData('api-other', () => $fetch('/api/other')).data).toEqualTypeOf>() expectTypeOf(useAsyncData('api-generics', () => $fetch('/test')).data).toEqualTypeOf>() - expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() - expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() + expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() + expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-hello', () => $fetch('/api/hello')).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-hey', () => $fetch('/api/hey')).data).toEqualTypeOf>() @@ -37,8 +37,8 @@ describe('API routes', () => { expectTypeOf(useLazyAsyncData('lazy-api-other', () => $fetch('/api/other')).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-generics', () => $fetch('/test')).data).toEqualTypeOf>() - expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() - expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() + expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() + expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf>() }) it('works with useFetch', () => { @@ -48,8 +48,8 @@ describe('API routes', () => { expectTypeOf(useFetch('/api/other').data).toEqualTypeOf>() expectTypeOf(useFetch('/test').data).toEqualTypeOf>() - expectTypeOf(useFetch('/error').error).toEqualTypeOf>() - expectTypeOf(useFetch('/error').error).toEqualTypeOf>() + expectTypeOf(useFetch('/error').error).toEqualTypeOf>() + expectTypeOf(useFetch('/error').error).toEqualTypeOf>() expectTypeOf(useLazyFetch('/api/hello').data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/api/hey').data).toEqualTypeOf>() @@ -58,8 +58,8 @@ describe('API routes', () => { expectTypeOf(useLazyFetch('/api/other').data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/test').data).toEqualTypeOf>() - expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf>() - expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf>() + expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf>() + expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf>() }) })