mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 07:32:01 +00:00
fix(nuxt): pass async-data errors through to client (#8521)
This commit is contained in:
parent
b719f1bb21
commit
bdacfa6ffe
@ -1,6 +1,7 @@
|
|||||||
import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref } from 'vue'
|
import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref } from 'vue'
|
||||||
import type { Ref, WatchSource } from 'vue'
|
import type { Ref, WatchSource } from 'vue'
|
||||||
import { NuxtApp, useNuxtApp } from '../nuxt'
|
import { NuxtApp, useNuxtApp } from '../nuxt'
|
||||||
|
import { createError } from './error'
|
||||||
|
|
||||||
export type _Transform<Input = any, Output = any> = (input: Input) => Output
|
export type _Transform<Input = any, Output = any> = (input: Input) => Output
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ export function useAsyncData<
|
|||||||
> (
|
> (
|
||||||
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
||||||
options?: AsyncDataOptions<DataT, Transform, PickKeys>
|
options?: AsyncDataOptions<DataT, Transform, PickKeys>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null>
|
||||||
export function useAsyncData<
|
export function useAsyncData<
|
||||||
DataT,
|
DataT,
|
||||||
DataE = Error,
|
DataE = Error,
|
||||||
@ -71,13 +72,13 @@ export function useAsyncData<
|
|||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
||||||
options?: AsyncDataOptions<DataT, Transform, PickKeys>
|
options?: AsyncDataOptions<DataT, Transform, PickKeys>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null>
|
||||||
export function useAsyncData<
|
export function useAsyncData<
|
||||||
DataT,
|
DataT,
|
||||||
DataE = Error,
|
DataE = Error,
|
||||||
Transform extends _Transform<DataT> = _Transform<DataT, DataT>,
|
Transform extends _Transform<DataT> = _Transform<DataT, DataT>,
|
||||||
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
||||||
> (...args: any[]): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true> {
|
> (...args: any[]): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null> {
|
||||||
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
||||||
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ export function useAsyncData<
|
|||||||
nuxt._asyncData[key] = {
|
nuxt._asyncData[key] = {
|
||||||
data: ref(useInitialCache() ? nuxt.payload.data[key] : options.default?.() ?? null),
|
data: ref(useInitialCache() ? nuxt.payload.data[key] : options.default?.() ?? null),
|
||||||
pending: ref(!useInitialCache()),
|
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
|
// TODO: Else, Soemhow check for confliciting keys with different defaults or fetcher
|
||||||
@ -168,7 +169,8 @@ export function useAsyncData<
|
|||||||
asyncData.pending.value = false
|
asyncData.pending.value = false
|
||||||
nuxt.payload.data[key] = asyncData.data.value
|
nuxt.payload.data[key] = asyncData.data.value
|
||||||
if (asyncData.error.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]
|
delete nuxt._asyncDataPromises[key]
|
||||||
})
|
})
|
||||||
@ -240,7 +242,7 @@ export function useLazyAsyncData<
|
|||||||
> (
|
> (
|
||||||
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
||||||
options?: Omit<AsyncDataOptions<DataT, Transform, PickKeys>, 'lazy'>
|
options?: Omit<AsyncDataOptions<DataT, Transform, PickKeys>, 'lazy'>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null>
|
||||||
export function useLazyAsyncData<
|
export function useLazyAsyncData<
|
||||||
DataT,
|
DataT,
|
||||||
DataE = Error,
|
DataE = Error,
|
||||||
@ -250,13 +252,13 @@ export function useLazyAsyncData<
|
|||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
handler: (ctx?: NuxtApp) => Promise<DataT>,
|
||||||
options?: Omit<AsyncDataOptions<DataT, Transform, PickKeys>, 'lazy'>
|
options?: Omit<AsyncDataOptions<DataT, Transform, PickKeys>, 'lazy'>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null>
|
||||||
export function useLazyAsyncData<
|
export function useLazyAsyncData<
|
||||||
DataT,
|
DataT,
|
||||||
DataE = Error,
|
DataE = Error,
|
||||||
Transform extends _Transform<DataT> = _Transform<DataT, DataT>,
|
Transform extends _Transform<DataT> = _Transform<DataT, DataT>,
|
||||||
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
||||||
> (...args: any[]): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null | true> {
|
> (...args: any[]): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, DataE | null> {
|
||||||
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
||||||
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
||||||
const [key, handler, options] = args as [string, (ctx?: NuxtApp) => Promise<DataT>, AsyncDataOptions<DataT, Transform, PickKeys>]
|
const [key, handler, options] = args as [string, (ctx?: NuxtApp) => Promise<DataT>, AsyncDataOptions<DataT, Transform, PickKeys>]
|
||||||
|
@ -30,7 +30,7 @@ export function useFetch<
|
|||||||
> (
|
> (
|
||||||
request: Ref<ReqT> | ReqT | (() => ReqT),
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
||||||
opts?: UseFetchOptions<_ResT, Transform, PickKeys>
|
opts?: UseFetchOptions<_ResT, Transform, PickKeys>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>
|
||||||
export function useFetch<
|
export function useFetch<
|
||||||
ResT = void,
|
ResT = void,
|
||||||
ErrorT = FetchError,
|
ErrorT = FetchError,
|
||||||
@ -114,7 +114,7 @@ export function useLazyFetch<
|
|||||||
> (
|
> (
|
||||||
request: Ref<ReqT> | ReqT | (() => ReqT),
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
||||||
opts?: Omit<UseFetchOptions<_ResT, Transform, PickKeys>, 'lazy'>
|
opts?: Omit<UseFetchOptions<_ResT, Transform, PickKeys>, 'lazy'>
|
||||||
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null | true>
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>
|
||||||
export function useLazyFetch<
|
export function useLazyFetch<
|
||||||
ResT = void,
|
ResT = void,
|
||||||
ErrorT = FetchError,
|
ErrorT = FetchError,
|
||||||
|
16
test/fixtures/basic/types.ts
vendored
16
test/fixtures/basic/types.ts
vendored
@ -28,8 +28,8 @@ describe('API routes', () => {
|
|||||||
expectTypeOf(useAsyncData('api-other', () => $fetch('/api/other')).data).toEqualTypeOf<Ref<unknown>>()
|
expectTypeOf(useAsyncData('api-other', () => $fetch('/api/other')).data).toEqualTypeOf<Ref<unknown>>()
|
||||||
expectTypeOf(useAsyncData<TestResponse>('api-generics', () => $fetch('/test')).data).toEqualTypeOf<Ref<TestResponse>>()
|
expectTypeOf(useAsyncData<TestResponse>('api-generics', () => $fetch('/test')).data).toEqualTypeOf<Ref<TestResponse>>()
|
||||||
|
|
||||||
expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<Error | true | null>>()
|
expectTypeOf(useAsyncData('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<Error | null>>()
|
||||||
expectTypeOf(useAsyncData<any, string>('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<string | true | null>>()
|
expectTypeOf(useAsyncData<any, string>('api-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<string | null>>()
|
||||||
|
|
||||||
expectTypeOf(useLazyAsyncData('lazy-api-hello', () => $fetch('/api/hello')).data).toEqualTypeOf<Ref<string>>()
|
expectTypeOf(useLazyAsyncData('lazy-api-hello', () => $fetch('/api/hello')).data).toEqualTypeOf<Ref<string>>()
|
||||||
expectTypeOf(useLazyAsyncData('lazy-api-hey', () => $fetch('/api/hey')).data).toEqualTypeOf<Ref<{ foo: string, baz: string }>>()
|
expectTypeOf(useLazyAsyncData('lazy-api-hey', () => $fetch('/api/hey')).data).toEqualTypeOf<Ref<{ foo: string, baz: string }>>()
|
||||||
@ -37,8 +37,8 @@ describe('API routes', () => {
|
|||||||
expectTypeOf(useLazyAsyncData('lazy-api-other', () => $fetch('/api/other')).data).toEqualTypeOf<Ref<unknown>>()
|
expectTypeOf(useLazyAsyncData('lazy-api-other', () => $fetch('/api/other')).data).toEqualTypeOf<Ref<unknown>>()
|
||||||
expectTypeOf(useLazyAsyncData<TestResponse>('lazy-api-generics', () => $fetch('/test')).data).toEqualTypeOf<Ref<TestResponse>>()
|
expectTypeOf(useLazyAsyncData<TestResponse>('lazy-api-generics', () => $fetch('/test')).data).toEqualTypeOf<Ref<TestResponse>>()
|
||||||
|
|
||||||
expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<Error | true | null>>()
|
expectTypeOf(useLazyAsyncData('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<Error | null>>()
|
||||||
expectTypeOf(useLazyAsyncData<any, string>('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<string | true | null>>()
|
expectTypeOf(useLazyAsyncData<any, string>('lazy-error-generics', () => $fetch('/error')).error).toEqualTypeOf<Ref<string | null>>()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('works with useFetch', () => {
|
it('works with useFetch', () => {
|
||||||
@ -48,8 +48,8 @@ describe('API routes', () => {
|
|||||||
expectTypeOf(useFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>()
|
expectTypeOf(useFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>()
|
||||||
expectTypeOf(useFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse>>()
|
expectTypeOf(useFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse>>()
|
||||||
|
|
||||||
expectTypeOf(useFetch('/error').error).toEqualTypeOf<Ref<FetchError | null | true>>()
|
expectTypeOf(useFetch('/error').error).toEqualTypeOf<Ref<FetchError | null>>()
|
||||||
expectTypeOf(useFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null | true>>()
|
expectTypeOf(useFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null>>()
|
||||||
|
|
||||||
expectTypeOf(useLazyFetch('/api/hello').data).toEqualTypeOf<Ref<string>>()
|
expectTypeOf(useLazyFetch('/api/hello').data).toEqualTypeOf<Ref<string>>()
|
||||||
expectTypeOf(useLazyFetch('/api/hey').data).toEqualTypeOf<Ref<{ foo: string, baz: string }>>()
|
expectTypeOf(useLazyFetch('/api/hey').data).toEqualTypeOf<Ref<{ foo: string, baz: string }>>()
|
||||||
@ -58,8 +58,8 @@ describe('API routes', () => {
|
|||||||
expectTypeOf(useLazyFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>()
|
expectTypeOf(useLazyFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>()
|
||||||
expectTypeOf(useLazyFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse>>()
|
expectTypeOf(useLazyFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse>>()
|
||||||
|
|
||||||
expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf<Ref<FetchError | null | true>>()
|
expectTypeOf(useLazyFetch('/error').error).toEqualTypeOf<Ref<FetchError | null>>()
|
||||||
expectTypeOf(useLazyFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null | true>>()
|
expectTypeOf(useLazyFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null>>()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user