如何使用 React-Apollo 处理 GraphQL 错误?

Posted

技术标签:

【中文标题】如何使用 React-Apollo 处理 GraphQL 错误?【英文标题】:How to handle GraphQL errors with React-Apollo? 【发布时间】:2018-01-28 22:47:13 【问题描述】:

我正在尝试使用服务器上的 Express + Mongoose 和客户端上的 React + Apollo 从 Rest API 迁移到 GraphQL。

async resolve(_,  email, password, passwordConfirmation )  // Sign Up mutation
            const user = new User( email );
            user.password = password;
            user.passwordConfirmation = passwordConfirmation;
            try
                const createdUser = await user.save();
                return createdUser;
             catch(error) 
                console.log(error); // Returns errors object like email: message: 'E-mail is required'
                throw new Error(error); // But on the client there is a string with all errors
            
        `

如何处理客户端的整个错误对象?

【问题讨论】:

【参考方案1】:

当您进行突变时,Apollo 客户端会返回一个承诺。可以在突变的结果承诺的 catch 块中访问来自该承诺的错误。请参阅下面的示例。

如果我的登录突变出现错误,我将在返回的 promise 的 catch 块中访问它们,然后将这些错误设置为组件中的本地状态。如果存在错误,则可以从那里渲染错误,或者如果您愿意,甚至可以将其传递给要渲染的子组件。请注意,错误通常以数组的形式返回。

class LoginForm extends Component 
  constructor(props) 
    super(props);

    this.state =  errors: [] ;
  


  onSubmit( email, password ) 
    this.props.mutate(
      variables:  email, password ,
      refetchQueries: [ query ]
    ).catch(res => 
      const errors = res.graphQLErrors.map(error => error.message);
      this.setState( errors );
    );
  

  render() 
    return (
      <div>
        <AuthForm
          errors=this.state.errors
          onSubmit=this.onSubmit.bind(this)
        />
      </div>
    );
  


export default graphql(query)(
  graphql(mutation)(LoginForm)
);

【讨论】:

【参考方案2】:

您还可以在 react-apollo 中使用 renderProps,它会在第二个参数中为您的对象提供错误和加载状态。

import React,  Component  from 'react';
import  Mutation  from 'react-apollo';
import gql from 'graphql-tag';
import Error from './ErrorMessage';

const LOGIN_MUTATION = gql`
  mutation LOGIN_MUTATION($email: String!, $password: String!) 
    signin(email: $email, password: $password) 
      id
      email
      name
    
  
`;

class Login extends Component 
  state = 
    name: '',
    password: '',
    email: '',
  ;
  saveToState = e => 
    this.setState( [e.target.name]: e.target.value );
  ;
  render() 
    return (
      <Mutation
        mutation=LOGIN_MUTATION
        variables=this.state
      >
        (login,  error, loading ) => (
          <form
            method="post"
            onSubmit=async e => 
              e.preventDefault();
              await login();
              this.setState( name: '', email: '', password: '' );
            
          >
            <fieldset disabled=loading>
              <h2>Sign into your account</h2>
              <Error error=error />
              <label htmlFor="email">
                Email
                <input
                  type="email"
                  name="email"
                  placeholder="email"
                  value=this.state.email
                  onChange=this.saveToState
                />
              </label>
              <label htmlFor="password">
                Password
                <input
                  type="password"
                  name="password"
                  placeholder="password"
                  value=this.state.password
                  onChange=this.saveToState
                />
              </label>

              <button type="submit">Sign In!</button>
            </fieldset>
          </form>
        )
      </Mutation>
    );
  


export default Login;

希望这会有所帮助!

【讨论】:

以上是关于如何使用 React-Apollo 处理 GraphQL 错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-apollo 中等待多个 useLazyQuery

批处理模式 Graphene 以状态 400“批处理请求应该收到一个列表”响应 React-Apollo 请求

如何使用带有 react-apollo 的模拟数据进行测试

如何使用 react-apollo 运行 graphQL 查询?

GraphQL、react-apollo、Apollo 1,全局处理 200 HTTP 代码状态的 data.error 错误。不是网络一。

如何使用 react-apollo 使用相同的查询进行多个 graphql 查询?