diff --git a/packages/toolkit/src/query/core/buildThunks.ts b/packages/toolkit/src/query/core/buildThunks.ts index 8a5dcc38ba..4592ea607d 100644 --- a/packages/toolkit/src/query/core/buildThunks.ts +++ b/packages/toolkit/src/query/core/buildThunks.ts @@ -302,6 +302,39 @@ export function buildThunks< baseQuery(arg, baseQueryApi, endpointDefinition.extraOptions as any) ) } + if ( + typeof process !== 'undefined' && + process.env.NODE_ENV === 'development' + ) { + const what = endpointDefinition.query ? '`baseQuery`' : '`queryFn`' + let err: undefined | string + if (!result) { + err = `${what} did not return anything.` + } else if (typeof result !== 'object') { + err = `${what} did not return an object.` + } else if (result.error && result.data) { + err = `${what} returned an object containing both \`error\` and \`result\`.` + } else if (result.error === undefined && result.data === undefined) { + err = `${what} returned an object containing neither a valid \`error\` and \`result\`. At least one of them should not be \`undefined\`` + } else { + for (const key of Object.keys(result)) { + if (key !== 'error' && key !== 'data' && key !== 'meta') { + err = `The object returned by ${what} has the unknown property ${key}.` + break + } + } + } + if (err) { + console.error( + `Error encountered handling the endpoint ${arg.endpointName}. + ${err} + It needs to return an object with either the shape \`{ data: }\` or \`{ error: }\` that may contain an optional \`meta\` property. + Object returned was:`, + result + ) + } + } + if (result.error) throw new HandledError(result.error, result.meta) return fulfillWithValue( diff --git a/packages/toolkit/src/query/fetchBaseQuery.ts b/packages/toolkit/src/query/fetchBaseQuery.ts index 5349ca3770..bd606b7cf7 100644 --- a/packages/toolkit/src/query/fetchBaseQuery.ts +++ b/packages/toolkit/src/query/fetchBaseQuery.ts @@ -54,7 +54,7 @@ const handleResponse = async ( if (responseHandler === 'json') { const text = await response.text() - return text.length ? JSON.parse(text) : undefined + return text.length ? JSON.parse(text) : null } } diff --git a/packages/toolkit/src/query/tests/apiProvider.test.tsx b/packages/toolkit/src/query/tests/apiProvider.test.tsx index 80ed29b36a..3da38e1579 100644 --- a/packages/toolkit/src/query/tests/apiProvider.test.tsx +++ b/packages/toolkit/src/query/tests/apiProvider.test.tsx @@ -6,7 +6,7 @@ import { waitMs } from './helpers' const api = createApi({ baseQuery: async (arg: any) => { await waitMs() - return { data: arg?.body ? arg.body : undefined } + return { data: arg?.body ? arg.body : null } }, endpoints: (build) => ({ getUser: build.query({ diff --git a/packages/toolkit/src/query/tests/buildThunks.test.tsx b/packages/toolkit/src/query/tests/buildThunks.test.tsx index f5997ca94d..c591738d01 100644 --- a/packages/toolkit/src/query/tests/buildThunks.test.tsx +++ b/packages/toolkit/src/query/tests/buildThunks.test.tsx @@ -74,7 +74,7 @@ test('passes the extraArgument property to the baseQueryApi', async () => { describe('re-triggering behavior on arg change', () => { const api = createApi({ - baseQuery: () => ({ data: undefined }), + baseQuery: () => ({ data: null }), endpoints: (build) => ({ getUser: build.query({ query: (obj) => obj, diff --git a/packages/toolkit/src/query/tests/cleanup.test.tsx b/packages/toolkit/src/query/tests/cleanup.test.tsx index 1b96d72361..957a5bbe18 100644 --- a/packages/toolkit/src/query/tests/cleanup.test.tsx +++ b/packages/toolkit/src/query/tests/cleanup.test.tsx @@ -7,7 +7,7 @@ import { render, waitFor } from '@testing-library/react' import { setupApiStore } from './helpers' const api = createApi({ - baseQuery: () => ({ data: undefined }), + baseQuery: () => ({ data: null }), endpoints: (build) => ({ a: build.query({ query: () => '' }), b: build.query({ query: () => '' }), diff --git a/packages/toolkit/src/query/tests/createApi.test.ts b/packages/toolkit/src/query/tests/createApi.test.ts index dcce29815e..90c9acb772 100644 --- a/packages/toolkit/src/query/tests/createApi.test.ts +++ b/packages/toolkit/src/query/tests/createApi.test.ts @@ -136,7 +136,7 @@ describe('wrong tagTypes log errors', () => { }) beforeEach(() => { - baseQuery.mockResolvedValue({}) + baseQuery.mockResolvedValue({ data: 'foo' }) }) test.each<[keyof typeof api.endpoints, boolean?]>([ diff --git a/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx b/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx index eb6b6bbc2a..9007a2dceb 100644 --- a/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx +++ b/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx @@ -101,7 +101,7 @@ describe('fetchBaseQuery', () => { expect(res).toBeInstanceOf(Object) expect(res.meta?.request).toBeInstanceOf(Request) expect(res.meta?.response).toBeInstanceOf(Object) - expect(res.data).toBeUndefined() + expect(res.data).toBeNull() }) it('should return an error and status for error responses', async () => {