Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DX Improvement for moving to @apollo/client v3 with bad mocks #8151

Open
magicmark opened this issue May 6, 2021 · 2 comments
Open

DX Improvement for moving to @apollo/client v3 with bad mocks #8151

magicmark opened this issue May 6, 2021 · 2 comments

Comments

@magicmark
Copy link
Contributor

magicmark commented May 6, 2021

First off, let me say <3 for all the effort y'all put into to making this library great! The improvements of v3 look awesome :)

This ticket is the result of a few solid days of me tracking down a bug in our code when trying to upgrade.

The tl;dr is that bad code in v2 could silently fail. When upgrading to v3, we get an assertion error that was difficult to debug. I'd like to suggest adding more actionable information and suggestions in the error message.

I know this is edge casey, but let me take you on this journey anyway - and maybe this might help future folks who run into this and google their stack trace.

Status Quo

Apollo versions

We're on 3.x for @apollo/react-{hooks,common,testing}

(The behaviour is different for 4.x, more details below)

$ cat package.json | grep apollo
    "@apollo/react-common": "^3.1.2",
    "@apollo/react-hooks": "^3.1.2",
    "@apollo/react-testing": "^3.1.2",
    "apollo": "^2.30.2",
    "apollo-cache-inmemory": "^1.6.3",
    "apollo-client": "^2.6.4",
    "apollo-link": "^1.2.13",
    "apollo-link-batch-http": "^1.2.9",
    "apollo-link-context": "^1.0.19",
    "apollo-link-error": "^1.1.12",

Code

Full Minimal Repro: https://glitch.com/edit/#!/educated-lydian-editorial
(you can open the terminal and run npm test)

Here's the relevant bits:

App.js
import * as React from "react";
import { gql } from "apollo-boost";
import { useQuery, ApolloProvider } from "@apollo/react-hooks";
import getApolloClient from "./apolloclient";

export const GET_VEHICLE = gql`
  query GetVehcile {
    vehicle(id: "dmVoaWNsZXM6NDI=") {
      name
    }
  }
`;

export function DisplayVehicle() {
  const { error, loading, data } = useQuery(GET_VEHICLE);

  if (error || loading) {
    return null;
  }

  return <p>Vehicle info: {JSON.stringify(data)}</p>;
}

export default function App() {
  return (
    <ApolloProvider client={getApolloClient()}>
      <DisplayVehicle />
    </ApolloProvider>
  );
}
test.js
import * as React from "react";
import wait from "waait";
import { MockedProvider } from "@apollo/react-testing";
import { act, render, prettyDOM } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import { DisplayVehicle, GET_VEHICLE } from "../App";

const MY_MOCKS = [
  {
    request: {
      query: GET_VEHICLE
    },
    result: {
      error: true
    }
  }
];

it("displays nothing for an error", async () => {
  const { baseElement, debug } = render(
    <MockedProvider mocks={MY_MOCKS} addTypename={false}>
      <DisplayVehicle />
    </MockedProvider>
  );

  await act(() => wait(0));

  debug();
  expect(baseElement).not.toHaveTextContent('Vehicle info');
});

The big problem here is that setting result.error = true in the mock is not the right way to test an error state, per the docs.

But it's an understandable, easy mistake to make. It looks like it could be correct. And in fact, the test fails as expected, because in @apollo/react-* @ 3.x, this bubbles up to become a Network error, and is caught by the error handling logic in the test as "expected".

 ApolloError: Network error: Error writing result to store for query:
full stack trace
ApolloError: Network error: Error writing result to store for query:
     {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetVehcile"},"variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"vehicle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"StringValue","value":"dmVoaWNsZXM6NDI=","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":81}}
    Cannot read property 'vehicle' of undefined
        at new ApolloError (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:92:26)
        at ObservableQuery.getCurrentResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:218:20)
        at QueryData.getQueryResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:357:56)
        at QueryData._this.getExecuteResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:111:26)
        at QueryData.execute (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:160:47)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:518:55
        at useDeepMemo (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:465:14)
        at useBaseQuery (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:517:16)
        at useQuery (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-hooks/3.1.5/node_modules/@apollo/react-hooks/lib/react-hooks.cjs.js:539:10)
        at DisplayVehicle (/app/App.js:17:36)
        at renderWithHooks (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:14985:18)
        at updateFunctionComponent (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:17356:20)
        at beginWork (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:19063:16)
        at beginWork$1 (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:23940:14)
        at performUnitOfWork (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:22779:12)
        at workLoopSync (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:22707:5)
        at renderRootSync (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:22670:7)
        at performSyncWorkOnRoot (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:22293:18)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:11327:26
        at unstable_runWithPriority (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/scheduler/0.20.2/node_modules/scheduler/cjs/scheduler.development.js:468:12)
        at runWithPriority$1 (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:11276:10)
        at flushSyncCallbackQueueImpl (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:11322:9)
        at flushSyncCallbackQueue (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:11309:3)
        at scheduleUpdateOnFiber (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:21893:9)
        at dispatchAction (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/react-dom/17.0.2/node_modules/react-dom/cjs/react-dom.development.js:16139:5)
        at runNextTicks (internal/process/task_queues.js:54:5)
        at listOnTimeout (internal/timers.js:501:9)
        at processTimers (internal/timers.js:475:7) {
      graphQLErrors: [],
      networkError: TypeError: Cannot read property 'vehicle' of undefined
          at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-cache-inmemory/1.6.6/node_modules/apollo-cache-inmemory/lib/bundle.cjs.js:759:27
          at Array.forEach (<anonymous>)
          at StoreWriter.writeSelectionSetToStore (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-cache-inmemory/1.6.6/node_modules/apollo-cache-inmemory/lib/bundle.cjs.js:750:29)
          at StoreWriter.writeResultToStore (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-cache-inmemory/1.6.6/node_modules/apollo-cache-inmemory/lib/bundle.cjs.js:722:19)
          at InMemoryCache.write (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-cache-inmemory/1.6.6/node_modules/apollo-cache-inmemory/lib/bundle.cjs.js:1144:22)
          at DataStore.markQueryResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:2309:20)
          at QueryManager.markQueryResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:1545:24)
          at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:2123:19
          at Object.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:322:23)
          at notifySubscription (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:135:18)
          at onNotify (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:179:3)
          at SubscriptionObserver.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:235:7)
          at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:1102:36
          at Set.forEach (<anonymous>)
          at Object.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/apollo-client/2.6.10/node_modules/apollo-client/bundle.umd.js:1101:21)
          at notifySubscription (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:135:18)
          at onNotify (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:179:3)
          at SubscriptionObserver.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:235:7)
          at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/react-testing/3.1.4/node_modules/@apollo/react-testing/lib/react-testing.cjs.js:110:22
          at Timeout.task [as _onTimeout] (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/jsdom/16.5.3/node_modules/jsdom/lib/jsdom/browser/Window.js:516:19)
          at listOnTimeout (internal/timers.js:531:17)
          at processTimers (internal/timers.js:475:7) {
        type: 'WriteError'
      },
      message: 'Network error: Error writing result to store for query:\n ' +
        '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetVehcile"},"variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"vehicle"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"StringValue","value":"dmVoaWNsZXM6NDI=","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":81}}\n' +
        "Cannot read property 'vehicle' of undefined",
      extraInfo: undefined
    }

So the error gets caught, and the test "works" (renders null) as the dev expects, but for the wrong reasons.

(I notice that on @apollo/react-* @ 4.x, the behaviour changed and we do get a different error that makes the test break. TODO: add stack trace)

@apollo/client v3

When I moved to @apollo/client @ 3.x, the test starts failing with Error: Uncaught [Invariant Violation: Missing field 'vehicle' in {}]:

full stack trace
    Error: Uncaught [Invariant Violation: Missing field 'vehicle' in {}]
        at reportException (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/jsdom/16.5.3/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:62:24)
        at Timeout.task [as _onTimeout] (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/jsdom/16.5.3/node_modules/jsdom/lib/jsdom/browser/Window.js:521:9)
        at listOnTimeout (internal/timers.js:531:17)
        at processTimers (internal/timers.js:475:7) Invariant Violation: Missing field 'vehicle' in {}
        at new InvariantError (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/ts-invariant/0.7.3/node_modules/ts-invariant/lib/invariant.esm.js:12:28)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/writeToStore.js:102:91
        at Set.forEach (<anonymous>)
        at StoreWriter.Object.<anonymous>.StoreWriter.processSelectionSet (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/writeToStore.js:66:17)
        at StoreWriter.Object.<anonymous>.StoreWriter.writeToStore (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/writeToStore.js:17:24)
        at InMemoryCache.Object.<anonymous>.InMemoryCache.write (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js:90:37)
        at InMemoryCache.Object.<anonymous>.ApolloCache.writeQuery (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/core/cache.js:46:21)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/core/QueryInfo.js:188:31
        at perform (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js:200:17)
        at InMemoryCache.Object.<anonymous>.InMemoryCache.performTransaction (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js:217:13)
        at QueryInfo.Object.<anonymous>.QueryInfo.markResult (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/core/QueryInfo.js:186:28)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/core/QueryManager.js:521:27
        at both (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/asyncMap.js:16:53)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/asyncMap.js:9:72
        at new Promise (<anonymous>)
        at Object.then (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/asyncMap.js:9:24)
        at Object.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/asyncMap.js:17:49)
        at notifySubscription (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:135:18)
        at onNotify (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:179:3)
        at SubscriptionObserver.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:235:7)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/iteration.js:4:68
        at Array.forEach (<anonymous>)
        at iterateObserversSafely (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/iteration.js:4:25)
        at Object.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/observables/Concast.js:25:21)
        at notifySubscription (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:135:18)
        at onNotify (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:179:3)
        at SubscriptionObserver.next (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/zen-observable/0.8.15/node_modules/zen-observable/lib/Observable.js:235:7)
        at /rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/@apollo/client/3.3.15/node_modules/@apollo/client/utilities/testing/mocking/mockLink.js:85:38
        at Timeout.task (/rbd/pnpm-volume/4c4c6f64-dcef-440d-91a6-6b40ff49a10c/node_modules/.registry.npmjs.org/jsdom/16.5.3/node_modules/jsdom/lib/jsdom/browser/Window.js:516:19)
        at listOnTimeout (internal/timers.js:531:17)
        at processTimers (internal/timers.js:475:7) {
      framesToPop: 1,
      name: 'Invariant Violation'
    }

full repro: https://glitch.com/edit/#!/orange-coffee-mango

With hindsight, this is "expected" (looks like this was noticed in @apollo/react-* @ 4.x). But when trying to upgrade a pretty large codebase, this was something that took a while to debug.

The assertion error catches a proper userland bug and at least prevents a bad test from passing, so 👍

Recommendation

I would suggest adding more actionable feedback to this error message - something like:

Error: Uncaught [Invariant Violation: Missing field 'vehicle' in {}].

This indicates the response Apollo Client received was malformed, and does not contain the expected selection set of data in the query.

If you are in a test, ensure your mock response is in the correct shape. See link/to/docs.

<something about if you're not a in a test and a real GQL server is returning this, something has gone catastrophically wrong and you should file a bug or something>

Closing thoughts

Sorry for the long winded issue, but thought you'd appreciate the war story and experience upgrading.

Overall I love the simplicity of everything under @apollo/client and this is a great project. Thanks for all your hard work! <3


Versions

app@orange-coffee-mango:~ 19:17 
$ npx envinfo@latest --preset apollo --clipboard
npx: installed 1 in 9.575s

  System:
    OS: Linux 4.4 Ubuntu 16.04.6 LTS (Xenial Xerus)
  Binaries:
    Node: 12.0.0 - /opt/nvm/versions/node/v12/bin/node
    npm: 6.9.0 - /opt/nvm/versions/node/v12/bin/npm
  npmPackages:
    @apollo/client: 3.3.15 => 3.3.15 
@brainkim
Copy link
Contributor

Related: #8063

@magicmark
Copy link
Contributor Author

magicmark commented May 23, 2024

@hwillson @brainkim @jerelmiller is this still relevant? I see 3.7.7 looks to have improved things but i haven't tested it out yet:

https://github.com/apollographql/apollo-client/releases/tag/v3.7.7

Log a warning to the console when a mock passed to MockedProvider or MockLink cannot be matched to a query during a test. This makes it easier to debug user errors in the mock setup...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants