GraphQL 突变中的 onError

Posted

技术标签:

【中文标题】GraphQL 突变中的 onError【英文标题】:onError in GraphQL mutations 【发布时间】:2020-09-26 10:32:05 【问题描述】:

我正在尝试对 graphql 突变进行 onError 并意识到它们无法正常工作:

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

那么还有什么办法可以捕捉错误呢?在上一个问题中,有人告诉我使用 try catch 块进行突变不是一个好主意。

我正在尝试做这样的事情,有一个可能的解决方法:

我要求用户输入,然后运行查询。根据查询的结果,我渲染了一些Usercomponents。在用户组件中,我使用按钮来运行突变。

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>

通常该过程运行良好,但是当突变中出现Alert.alert('Contact Already Exists'); 错误时,就会产生问题。例如,在我关闭错误警报并运行新查询后,我应该只获得新的用户组件(即使我现在只运行查询,而不是突变)。但是,我也收到了Contact Already Addedalert。实际上它会弹出两次。

也许问题出在回调中。

像这样使用 .catch 是可行的,但没有其他方法可以做到这一点吗?由于我没有使用 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');
      
    );

【问题讨论】:

【参考方案1】:

您可以使用onError 回调而不是直接在函数体上从结果中检查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
);

注意:使用React.memo来记忆组件以避免不必要的重新渲染该组件

【讨论】:

一个开放的 GitHub 问题表明 onError 不适用于突变,但不知何故这有效 如果可能,请您提供问题链接吗?我很想知道他们注意到这个问题的场景是什么。 github.com/apollographql/apollo-client/issues/5708 我之前尝试过使用onError,但没有成功。也许我正在使用回调。 感谢您分享链接:)

以上是关于GraphQL 突变中的 onError的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 突变中的子类型

使用 Appsync 更新 GraphQL 中的突变

FaunaDB - 如何批量更新单个 graphQL 突变中的条目列表?

CORS 阻止 GraphQL Yoga 中的突变

在 GraphQL 中的相关类型之间创建突变

GraphQL 突变中的自定义类型