4

Im using react query as data handler. Im new to react native and kinda new to react query.

Right now i dont really understand why the onError callback is not handling my errors. The error callback is fired by the error still goes to the catch handler (that i dont want to have) in the function.

I have the following setup/structure:

Axios in API layer. No try catch. UseMutation setup with mutationFn pointing to the "axios API request". ClickHandler firing a function that doing the mutation.

const mutation = useMutation({
    mutationFn: (req: TimeReportRequest) => {
      return updateTimeReport(timeReport?.id!, req);
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['timeReports'] });
       
    },
    onError: (error) => {
      console.log('Im the error and i should not go further');
      errorMessageHandler(error);
    },
  });

const onSubmitTimeReport = () => {
    try {
      if (!timeReport) return;
      const req: TimeReportRequest = {
       ...
      };

      mutation.mutate(req);
    } catch (error) {
      console.log("im will recieve the error. But i shouldn't?. Error is not handled as a normal try-catch")
    }
    
  };
 

The main problem is that the error is not handled correct. If i remove react query and just use the API-layer (axios method) straight with try catch everything works as expected.

What am i missing here?

2 Answers 2

2

I will answer this question by my self because the main problem here was two things:

  • How react native and yellow box works with react query
  • How react query bubble events

First thing with react native, react query (in my case expo) is that all error codes >300 will be displayed as warnings from yellow box. I didnt know this and this is just a dev warning. Also if you wanna run a demo or something that should not display the warnings when lets say a API request returns 400 you could disable yellowbox to avoid unnecessary questions.

Second is that react query onError will not "catch" the error. It more acts like a middleware where you have the oppertunity to do stuff on error.

So in many scenarios you can choose to "catch" the error in the onError method or wrap you whole call in try catch. Or maby i certain scenarios you might need both.

Sign up to request clarification or add additional context in comments.

Comments

0

Instead of catching the error using Try catch. Try mutation.mutate(req, {onError: ()=> {}); Here is a better way to write mutation, instead on passing onError function when you create the hook, you can pass your error handler wherever you use the hook.

import type {
  MutationFunction,
  UseMutationOptions,
} from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import type { AxiosError, AxiosResponse } from 'axios';

const mutationFn: MutationFunction<AxiosResponse<Response>, Request> = ({
  ...data
}) =>
  client.post(`/url`, createFormData(data));

export const useCustomHook = (
  config?: UseMutationOptions<AxiosResponse<Response>, AxiosError, Request>
) =>
  useMutation<AxiosResponse<Response>, AxiosError, Request>(
    (data) => mutationFn(data),
    config
  );

To Use this Hook in any part of your application

const { mutate } = useCostumHook({
    onSuccess: () => {
      Alert.alert('Success', 'updated successfully');
    },
    onError: () => {
      Alert.alert('Error', 'Something went wrong');
    },
  });

I hope this helps

1 Comment

Agree that it could be a good pattern to pass the onSuccess and onError functions as callbacks to a custom hook. Thans for sharing. Doesnt really change anything of how the mutation is actually handling the error tho. I mean the result will be the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.