所有apollo查询错误都会导致网络400错误

时间:2018-04-16 10:42:08

标签: react-native expo react-apollo apollo-client

如何全局处理我的查询和变异错误?当我使用格式错误的graphql查询时,在变异或查询中,我的react-native应用程序总是会抛出以下错误。

  

未处理(在react-apollo:Apollo(MyScreen)中)错误:网络错误:   响应不成功:收到状态码400

在graphiql端点上运行相同的查询,但是会提供相关的错误。虽然目标是全局处理错误,但本地查询错误对我来说也不起作用。打印它们什么都没有。

//MyComponent.js
class MyComponent extends React.Component {
  render () {
    /*
    outputs
    {
      error: undefined
      loading: true
      networkStatus: 1
    }
    */
    console.log(this.props.data);
    //outputs undefined
    console.log('error', this.props.error);
    //outputs undefined
    console.log('errors', this.props.errors);

    return (
      <Container>
        {this.props.myData}
        <Button block onPress={this.props.onPress}>
          <Text>Button</Text>
        </Button>
      </Container>
    )
  }
}

const mapDispatchToProps = (dispatch, {navigation: {navigate}}) => ({
  onPress: async rest => {
    //do stuff
  }
});

export default connect(null, mapDispatchToProps)(MyDataService.getMyDataInjector(MyComponent));


//MyDataService.js
import { graphql } from 'react-apollo';
import getApolloClient from '../../../apolloClient';
import { dataFragment } from './dataFragments';
import gql from 'graphql-tag';

export default MyDataService = {

  getMyDataInjector: graphql(gql`
    query {
      myData {
        ...dataFragment
      }
    }
    ${dataFragment}
  `,
  {
    props: ({ data, errors, error }) => ({
      data,
      loading: data.loading,
      myData: data.myData,
      errors,
      error,
    })
  }),

  addData: async (data) => {
    const res = await apolloClient.mutate({
      mutation: gql`
        mutation addData($data: String!) {
          addData(data: $data) {
            ...dataFragment
          }
        }
        ${dataFragment}
      `,
      variables: {
        data,
      }
    });

    return res.data.addData;
  },
};


//apolloClient.js
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { onError } from 'apollo-link-error';
import { InMemoryCache, defaultDataIdFromObject  } from 'apollo-cache-inmemory';

let apolloClient;

const initApolloClient = store => {
  const httpLink = new HttpLink({uri: 'http://192.168.0.11:3000/graphql'})

  // const errorLink = onError(({ response, graphQLErrors, networkError }) => {
  //   console.log('graphql error in link', graphQLErrors);
  //   console.log('networkError error in link', networkError);
  //   console.log('response error in link', response);

  //   if (graphQLErrors)
  //     graphQLErrors.map(({ message, locations, path }) =>
  //       console.log(
  //         `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
  //       ),
  //     );
  //   if (networkError) console.log(`[Network error]: ${networkError}`);
  // });

  const authLink = setContext((_, { headers }) => {
    const {accessToken: {type, token}} = store.getState().signedInUser;
    return {
      headers: {
        ...headers,
        authorization: type && token ? type + ' ' + token : null 
      }
    }
  });

  apolloClient =  new ApolloClient({
    // using error link throws - Error: Network error: forward is not a function
    // link: authLink.concat(errorLink, httpLink),
    link: authLink.concat(httpLink),
    // doesn't console log
    // onError: (e) => { console.log('IN ON ERROR', e.graphQLErrors) },
    cache: new InMemoryCache({
      dataIdFromObject: o => (o._id ? `${o.__typename}:${o._id}`: null),
    }),
    // turning these on do nothing
    // defaultOptions: {
    //   query: {
    //     // fetchPolicy: 'network-only',
    //     errorPolicy: 'all',
    //   },
    //   mutate: {
    //     errorPolicy: 'all'
    //   }
    // }
  });

  return apolloClient;
}


export default getApolloClient = () => apolloClient;

export { initApolloClient };

1 个答案:

答案 0 :(得分:1)

能够通过使用带有onError的apollo-link来实现它。

import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { onError } from 'apollo-link-error';
import { InMemoryCache, defaultDataIdFromObject  } from 'apollo-cache-inmemory';

let apolloClient;

const initApolloClient = store => {
  const httpLink = new HttpLink({uri: 'http://192.168.0.11:3000/graphql'})

  const errorLink = onError(({ graphQLErrors, networkError }) => {
    if (graphQLErrors) {
      graphQLErrors.map(({ message, locations, path }) =>
        console.error(
          `[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`,
        ),
      );
    }

    if (networkError) console.error(`[Network error]: ${networkError}`);
  });

  const authLink = setContext((_, { headers }) => {
    const {accessToken: {type, token}} = store.getState().signedInUser;
    return {
      headers: {
        ...headers,
        authorization: type && token ? type + ' ' + token : null 
      }
    }
  });

  const link = ApolloLink.from([
    authLink,
    errorLink,
    httpLink,
  ]);

  apolloClient =  new ApolloClient({
    link,
    cache: new InMemoryCache({
      //why? see https://stackoverflow.com/questions/48840223/apollo-duplicates-first-result-to-every-node-in-array-of-edges/49249163#49249163
      dataIdFromObject: o => (o._id ? `${o.__typename}:${o._id}`: null),
    }),
  });

  return apolloClient;
}