React Native + React Query + onError 无法捕获和处理错误?

huangapple go评论48阅读模式
英文:

React native + react-query + onError does not catch and handle error?

问题

I'm using react query as a data handler. I'm new to react native and somewhat new to react query.

Right now, I don't really understand why the onError callback is not handling my errors. The error callback is fired, but the error still goes to the catch handler (which I don't want).

I have the following setup/structure:

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

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

What am I missing here?

英文:

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?

答案1

得分: 1

I will answer this question by myself 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 didn't know this, and this is just a dev warning. Also, if you want to run a demo or something that should not display the warnings when, let's say, an 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 opportunity to do stuff on error.

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

英文:

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.

答案2

得分: 0

Here is the translated content:

"不要使用Try catch来捕获错误。
尝试使用mutation.mutate(req, {onError: ()=> {});
这里有一种更好的方式来编写mutation,不是在创建hook时传递onError函数,而是在使用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
  );

在应用程序的任何部分使用这个Hook:

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

希望这有所帮助。"

英文:

Instead of catching the error using Try catch.
Try mutation.mutate(req, {onError: ()=&gt; {});
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.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

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

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

export const useCustomHook = (
  config?: UseMutationOptions&lt;AxiosResponse&lt;Response&gt;, AxiosError, Request&gt;
) =&gt;
  useMutation&lt;AxiosResponse&lt;Response&gt;, AxiosError, Request&gt;(
    (data) =&gt; mutationFn(data),
    config
  );

<!-- end snippet -->

To Use this Hook in any part of your application

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const { mutate } = useCostumHook({
    onSuccess: () =&gt; {
      Alert.alert(&#39;Success&#39;, &#39;updated successfully&#39;);
    },
    onError: () =&gt; {
      Alert.alert(&#39;Error&#39;, &#39;Something went wrong&#39;);
    },
  });

<!-- end snippet -->

I hope this helps

huangapple
  • 本文由 发表于 2023年4月13日 16:15:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定