Skip to content

Commit

Permalink
Prevent undefined response when onError is provided
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenn Creighton committed Apr 22, 2021
1 parent d77b6b4 commit e7a8071
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/react/data/MutationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,23 @@ export class MutationData<
return this.mutate(mutationFunctionOptions)
.then((response: FetchResult<TData>) => {
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;
}
});
};

Expand Down Expand Up @@ -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,
Expand All @@ -138,10 +148,6 @@ export class MutationData<
called: true
});
}

if (onError) {
onError(error);
}
}

private generateNewMutationId(): number {
Expand All @@ -152,13 +158,14 @@ export class MutationData<
return this.mostRecentMutationId === mutationId;
}

private updateResult(result: MutationResultWithoutClient<TData>) {
private updateResult(result: MutationResultWithoutClient<TData>): MutationResultWithoutClient<TData> | undefined {
if (
this.isMounted &&
(!this.previousResult || !equal(this.previousResult, result))
) {
this.setResult(result);
this.previousResult = result;
return result;
}
}
}
52 changes: 52 additions & 0 deletions src/react/hooks/__tests__/useMutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<MockedProvider mocks={mocks}>
<Component />
</MockedProvider>
);

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!'
Expand Down

0 comments on commit e7a8071

Please sign in to comment.