From 51a309cae1ed26b137da9ba5feea051fb61d4334 Mon Sep 17 00:00:00 2001 From: Jenn Creighton Date: Mon, 19 Apr 2021 10:30:45 -0400 Subject: [PATCH 1/2] Prevent undefined response when onError is provided --- src/react/data/MutationData.ts | 23 +++++--- .../hooks/__tests__/useMutation.test.tsx | 52 +++++++++++++++++++ 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/react/data/MutationData.ts b/src/react/data/MutationData.ts index 209cd8be6ac..7f8c9764ffd 100644 --- a/src/react/data/MutationData.ts +++ b/src/react/data/MutationData.ts @@ -71,11 +71,23 @@ export class MutationData< return this.mutate(mutationFunctionOptions) .then((response: FetchResult) => { this.onMutationCompleted(response, mutationId); + if (response.errors) { + + } return response; }) .catch((error: ApolloError) => { + const { onError } = this.getOptions(); this.onMutationError(error, mutationId); - if (!this.getOptions().onError) throw error; + if (onError) { + onError(error); + return { + data: undefined, + errors: error, + }; + } else { + throw error; + } }); }; @@ -128,8 +140,6 @@ export class MutationData< } private onMutationError(error: ApolloError, mutationId: number) { - const { onError } = this.getOptions(); - if (this.isMostRecentMutation(mutationId)) { this.updateResult({ loading: false, @@ -138,10 +148,6 @@ export class MutationData< called: true }); } - - if (onError) { - onError(error); - } } private generateNewMutationId(): number { @@ -152,13 +158,14 @@ export class MutationData< return this.mostRecentMutationId === mutationId; } - private updateResult(result: MutationResultWithoutClient) { + private updateResult(result: MutationResultWithoutClient): MutationResultWithoutClient | undefined { if ( this.isMounted && (!this.previousResult || !equal(this.previousResult, result)) ) { this.setResult(result); this.previousResult = result; + return result; } } } diff --git a/src/react/hooks/__tests__/useMutation.test.tsx b/src/react/hooks/__tests__/useMutation.test.tsx index de541810bb7..19985873fa5 100644 --- a/src/react/hooks/__tests__/useMutation.test.tsx +++ b/src/react/hooks/__tests__/useMutation.test.tsx @@ -252,6 +252,58 @@ describe('useMutation Hook', () => { }); describe('mutate function upon error', () => { + itAsync('resolves with the resulting data and errors', async (resolve, reject) => { + const variables = { + description: 'Get milk!' + }; + + const mocks = [ + { + request: { + query: CREATE_TODO_MUTATION, + variables + }, + result: { + data: CREATE_TODO_RESULT, + errors: [new GraphQLError(CREATE_TODO_ERROR)], + }, + } + ]; + + let fetchResult: any; + const Component = () => { + const [createTodo] = useMutation<{ createTodo: Todo }>( + CREATE_TODO_MUTATION, + { + onError: error => { + expect(error.message).toEqual(CREATE_TODO_ERROR); + } + } + ); + + async function runMutation() { + fetchResult = await createTodo({ variables }); + } + + useEffect(() => { + runMutation(); + }, []); + + return null; + }; + + render( + + + + ); + + await wait(() => { + expect(fetchResult.data).toEqual(undefined); + expect(fetchResult.errors.message).toEqual(CREATE_TODO_ERROR); + }).then(resolve, reject); + }); + it(`should reject when errorPolicy is 'none'`, async () => { const variables = { description: 'Get milk!' From c2a4e84fc8ee68483a2f61b3238d005442c03c5b Mon Sep 17 00:00:00 2001 From: Jenn Creighton Date: Wed, 21 Apr 2021 22:48:00 -0400 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ src/react/data/MutationData.ts | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3f056dd3ef..406e395a1e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ - During server-side rendering, allow initial `useQuery` calls to return final `{ loading: false, data }` results when the cache already contains the necessary data.
[@benjamn](https://github.com/benjamn) in [#7983](https://github.com/apollographql/apollo-client/pull/7983) +- Prevent `undefined` mutation result in useMutation
+ [@jcreighton](https://github.com/jcreighton) in [#8018](https://github.com/apollographql/apollo-client/pull/8018) + ## Apollo Client 3.3.14 ### Improvements diff --git a/src/react/data/MutationData.ts b/src/react/data/MutationData.ts index 7f8c9764ffd..e4e2bcd6c20 100644 --- a/src/react/data/MutationData.ts +++ b/src/react/data/MutationData.ts @@ -71,9 +71,6 @@ export class MutationData< return this.mutate(mutationFunctionOptions) .then((response: FetchResult) => { this.onMutationCompleted(response, mutationId); - if (response.errors) { - - } return response; }) .catch((error: ApolloError) => {