简体   繁体   English

GraphQL 突变中的 onError

[英]onError in GraphQL mutations

I was trying onError for graphql mutations and realised that they don't work properly:我正在为 graphql 突变尝试 onError 并意识到它们无法正常工作:

https://github.com/apollographql/apollo-client/issues/5708 https://github.com/apollographql/apollo-client/issues/5708

What else can be done for catching errors then?那么还有什么办法可以捕捉错误呢? In a previous question, I was told that using try catch blocks for mutations is not a good idea.在上一个问题中,有人告诉我使用 try catch 块进行突变不是一个好主意。

I am trying to do something like this, with a possible workaround:我正在尝试使用可能的解决方法来做这样的事情:

I ask user for an input, then run a query.我要求用户输入,然后运行查询。 Depending on the results of the query, I render some User components.根据查询的结果,我渲染了一些User组件。 From the user component, I use the button to run mutations.在用户组件中,我使用按钮运行突变。

export const AddContact: React.FunctionComponent = () => {
  const initialValues: FormValues = {
    phoneNumber: '',
  };

  const [isSubmitted, setIsSubmitted] = useState(false);
  const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
  const navigation = useNavigation();
  const validationSchema = phoneNumberValidationSchema;

  const _onLoadUserError = React.useCallback((error: ApolloError) => {
    Alert.alert('Unable to Add Contact');
  }, []);

  const [
    createUserRelationMutation,
    {
      data: addingContactData,
      loading: addingContactLoading,
      error: addingContactError,
      called: isMutationCalled,
    },
  ] = useCreateUserRelationMutation({
    onCompleted: () => {
      Alert.alert('Contact Added');
    },
  });


    const onAddContact = (id: number) => {
    setIsSubmitted(false);
    setUserData(null);
    createUserRelationMutation({
      variables: {
        input: { relatedUserId: id, type: RelationType.Contact, userId: 1 },
      },
    });
  }

  const getContactId = React.useCallback(
    (data: UsersLazyQueryHookResult) => {
      if (data) {
        if (data.users.nodes.length == 0) {
          Alert.alert('No User Found');
        } else {
          setUserData(data);
        }
      }
    },
    [onAddContact],
  );

  const [loadUsers] = useUsersLazyQuery({
    onCompleted: getContactId,
    onError: _onLoadUserError,
  });

  const handleSubmitForm = React.useCallback(
    (values: FormValues, helpers: FormikHelpers<FormValues>) => {
      setIsSubmitted(true);
      const plusSign = '+';
      const newPhoneNumber = plusSign.concat(values.phoneNumber);
      console.log('Submitted');
      loadUsers({
        variables: {
          where: { phoneNumber: newPhoneNumber },
        },
      });
      helpers.resetForm();
    },
    [loadUsers],
  );


    if (!addingContactLoading && isMutationCalled) {
    if (addingContactError) {
      console.log('this is the error', addingContactError);
      if ((addingContactError.toString()).includes('already exists')){
        Alert.alert('Contact Already Exists');
      }
      else{
      Alert.alert('Unable to Add Contact');
      }
    }
  }

  return (
...
)
 <User onAddContact={onAddContact} data={userData}></User>
...
export const User: React.FunctionComponent<UserProps> = ({
  data,
  onAddContact,
}) => {
  if (!data) return null;
  return (
                <Button
                  onPress={() => onAddContact(Number(item.id))}
                  >
                </Button>

Generally the process works fine but when's there's a Alert.alert('Contact Already Exists');一般来说,这个过程工作正常,但什么时候有Alert.alert('Contact Already Exists'); error in the mutation, it creates a problem.突变中的错误,它会产生一个问题。 For instance, after I close the error alert, and run a new query, I am supposed to get only the new User component (even though I am only running a query now, not a mutation).例如,在我关闭错误警报并运行新查询后,我应该只获得新的用户组件(即使我现在只运行查询,而不是突变)。 However, I also get the Contact Already Added alert.但是,我也收到“ Contact Already Added ”警报。 In fact it pops up twice.实际上它会弹出两次。

Maybe the problem is in the callbacks.也许问题出在回调中。

Using a.catch like this would work but is there no other way to do this?像这样使用 a.catch 会起作用,但没有其他方法可以做到这一点吗? Since I am not using catch for the query, the code would become inconsistent.由于我没有使用 catch 进行查询,因此代码会变得不一致。

.catch((err: any) => {
      console.log('errror', err)
      if ((err.toString()).includes('already exists')){
        console.log('working')
        Alert.alert('Contact Already Exists');
      }
      else{
      Alert.alert('Unable to Add Contact');
      }
    });

You could use onError callback instead of checking for addingContactError property from the result directly on function body like shown below您可以使用onError回调而不是直接在 function 主体上从结果中检查addingContactError属性,如下所示

const _onCreateUserRelationError = React.useCallback((error: ApolloError) => {
    console.log('this is the error', error);
    Alert.alert(error.message.includes('already exists') ? 'Contact Already Exists' : 'Unable to Add Contact');
}, []);

const [
    createUserRelationMutation,
    {
        data: addingContactData,
        loading: addingContactLoading,
        called: isMutationCalled,
    },
] = useCreateUserRelationMutation({
    onCompleted: () => {
        Alert.alert('Contact Added');
    },
    onError: _onCreateUserRelationError
});

Note: Memoize the component using React.memo to avoid unnecessary re-rendering of this component注意:使用React.memo对组件进行记忆,以避免不必要的重新渲染该组件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM