web-dev-qa-db-fra.com

Erreur: erreur réseau: erreur d'écriture du résultat à stocker pour la requête (client Apollo)

J'utilise Apollo Client pour créer une application pour interroger mon serveur à l'aide de Graphql. J'ai un serveur python sur lequel j'exécute mes requêtes graphql qui récupère les données de la base de données et les renvoie ensuite au client.

J'ai créé une interface réseau personnalisée pour le client qui m'aide à faire une demande de serveur personnalisée (par défaut, ApolloClient fait un appel POST à l'URL que nous spécifions). L'interface réseau ne doit avoir qu'un méthode query () dans laquelle nous renvoyons la promesse du résultat de la forme Promise<ExecutionResult>.

Je peux appeler le serveur et récupérer les données demandées, mais j'obtiens toujours l'erreur suivante.

Error: Network error: Error writing result to store for query 
{
   query something{
      row{
         data
      }
   }
}
Cannot read property 'row' of undefined
    at new ApolloError (ApolloError.js:32)
    at ObservableQuery.currentResult (ObservableQuery.js:76)
    at GraphQL.dataForChild (react-apollo.browser.umd.js:410)
    at GraphQL.render (react-apollo.browser.umd.js:448)
    at ReactCompositeComponent.js:796
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
    at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
    at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:746)
    at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:724)
    at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:645)
    at ReactCompositeComponentWrapper.performUpdateIfNecessary (ReactCompositeComponent.js:561)
    at Object.performUpdateIfNecessary (ReactReconciler.js:157)
    at runBatchedUpdates (ReactUpdates.js:150)
    at ReactReconcileTransaction.perform (Transaction.js:140)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:140)
    at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
    at Object.flushBatchedUpdates (ReactUpdates.js:172)
    at ReactDefaultBatchingStrategyTransaction.closeAll (Transaction.js:206)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:153)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.enqueueUpdate (ReactUpdates.js:200)

Je veux connaître la cause possible de l'erreur et la solution si possible.

25
return007

J'ai eu une erreur similaire. Je l'ai calculé en ajoutant un identifiant à la requête. par exemple, ma requête actuelle était

query  {
  service:me {
    productServices {
      id
      title
    }
  }
}

ma nouvelle requête était

query  {
  service:me {
    **id**
    productServices {
      id
      title
    }
  }
}
25
ibamboo

nous devons inclure id, sinon cela provoquera l'erreur mentionnée.

{
   query something {
      id
      row {
         id
         data
      }
   }
}
17
imdzeeshan

J'ai finalement découvert la cause de ce problème après l'avoir combattu dans diverses parties de notre application pendant des mois. Ce qui a aidé à faire la lumière sur ce changement, c'était de passer de apollo-cache-inmemory à apollo-cache-hermes.

J'ai expérimenté avec Hermes dans l'espoir d'atténuer ce problème, mais malheureusement, il ne parvient pas à mettre à jour le cache comme apollo-cache-inmemory. Ce qui est curieux cependant, c'est que hermes affiche un très joli message convivial, contrairement à apollo-cache-inmemory. Cela m'a amené à une révélation que le cache rencontre vraiment ce problème lorsqu'il essaie de stocker un type d'objet qui est déjà dans le cache avec un ID, mais que le nouveau type d'objet lui manque. Alors apollo-cache-inmemory devrait fonctionner correctement si vous êtes méticuleusement cohérent lorsque vous interrogez vos champs. Si vous omettez le champ id partout pour un certain type d'objet, cela fonctionnera avec plaisir. Si vous utilisez le champ id partout, cela fonctionnera correctement. Une fois que vous mélangez les requêtes avec et sans identifiant, le cache explose avec cet horrible message d'erreur.

Ce n'est pas un bug - il fonctionne comme prévu, il n'est simplement documenté nulle part - voyez ceci spec . Je souhaite vraiment qu'Apollo ait documenté cette contrainte quelque part.

8
Capaj

J'ai eu un problème similaire.

Peut-être que votre application tentait d'écrire (les données de réponse du réseau) dans le magasin avec la mauvaise adresse de magasin ?

Solution à mon problème

Je mettais à jour le magasin après avoir ajouté un player à un team:

// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
  const addr = { query: gql(QUERY_TEAM), variables: { _id } };
  const data = store.readQuery(addr);
  stored.teams.players.Push(response.data.player));
  store.writeQuery({...addr, data});
}

J'ai commencé à obtenir une erreur similaire ci-dessus (je suis sur Apollo 2.0.2)

Après avoir creusé dans le magasin, j'ai réalisé mon QUERY_TEAM demande faite avec une variable meta par défaut à null. Le magasin "adresse" semble utiliser le *stringified addr pour identifier l'enregistrement. J'ai donc changé mon code ci-dessus pour imiter le null:

// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
  const addr = { query: gql(QUERY_TEAM), variables: { _id, meta: null } };
  const data = store.readQuery(addr);
  data.teams.players.Push(response.data.player));
  store.writeQuery({...addr, data});
}

Et cela a résolu mon problème.

* La valeur par défaut de undefined au lieu de null évitera probablement ce bogue désagréable ( non vérifié )

Plus d'infos

Mon problème n'est peut-être que tangentiellement lié, donc si cela n'aide pas, j'ai deux conseils:

First, ajoutez ces 3 lignes à node_modules/apollo-cache-inmemory/lib/writeToStore.js pour vous alerter lorsque "l'enregistrement" est vide. Et puis enquêter sur _a pour comprendre ce qui ne va pas.

exports.writeResultToStore = writeResultToStore;
function writeSelectionSetToStore(_a) {

    var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context;
    var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap;

    +if (typeof result === 'undefined') {
    +    debugger;
    +}

Second, assurez-vous que toutes les requêtes, mutations et mises à jour manuelles du magasin sont enregistrées avec les variables que vous attendez

2
Ashley Coolman