This site looks healthier in portrait mode.

At Zocdoc, we use React components for our web views and GraphQL to fetch data from backend services. We use the open-source React Apollo library to incorporate the results of GraphQL queries into components. We also use server-side rendering for Search Engine Optimization. Recently, while refactoring some code, I identified a bug in React Apollo specific to server side rendering, and contributed a fix that is now available in the latest NPM version. This experience taught me a lot about how to contribute to open source projects, and I’m hoping to continue to do that, especially now that Hacktoberfest is here!

A puzzling error

A few months ago, I began working with React and GraphQL for the first time at Zocdoc, with no relevant prior front-end experience. While refactoring the render code of a component, I introduced an error in my local development environment by trying to render a new component without having imported its definition. When this happens and I try to load the affected page, I normally see a JavaScript error with text like Error: Component is not defined. In a situation similar to this, I instead saw a very confusing error:

stack: Error: 10 errors were thrown while executing your GraphQL queries.\n at …
Message: 10 errors were thrown while executing your GraphQL queries.
queryErrors:
[ { Error: 10 errors were thrown while executing your GraphQL queries.\n at …

The repeated text suggested to me that there was a circular reference. The first location in the stack trace was in a file called getDataFromTree, so I inspected the code in that file, which included this error handling logic:

const mappedPromises = promises.map(({ promise, context, instance }) => {
    return promise
      .then(_ => getDataFromTree(instance.render(), context))
      .catch(e => errors.push(e));
  });

  return Promise.all(mappedPromises).then(_ => {
    if (errors.length > 0) {
      const error =
        errors.length === 1
          ? errors[0]
          : new Error(
              `${errors.length} errors were thrown when executing your fetchData functions.`,
            );
      error.queryErrors = errors;
      throw error;
    }
  });

This code was contained inside a function that was recursively traversing the DOM and executing GraphQL queries for all components that had queries associated with them. To make troubleshooting easier, this code also added an error boundary that caught all errors thrown during this process and bundled them into a single wrapper error that contained references to the individual errors in a queryErrors property.

It seemed likely to me that there was a bug in this React Apollo code that was causing the behavior I observed. The bug I suspected would result in this unhelpful error message whenever a component with an associated GraphQL query contained multiple other components that had their own associated queries, and multiple of the inner components threw errors.

Contributing to open source

I reached out to Lucas Reis, a senior front-end engineer, for advice about how to proceed. Since this was a simple issue, Lucas suggested that I test my hypothesis by editing the dependency code directly in the node_modules folder of the project I was working on. If I was able to fix the bug, I should then proceed to fork the React Apollo repository and apply my fix to the fork, and open a pull request to get this incorporated into the open-source project. I followed these steps and, with the help of Zack Banton, another software engineer at Zocdoc, opened a pull request to fix this bug:

For a few weeks, I didn’t get any feedback on my fix pull request except from a bot that React Apollo has set up to help maintain the repository. I read about the project online to learn more about it, and discovered that Apollo has its own Slack open to the community, with individual channels for different projects, like apollo-client and React Apollo. I joined this Slack and asked about the status of my pull request in the channels dedicated to contributing and React Apollo. The developers who maintain the Apollo software were very friendly and promised to follow up, and they reviewed, approved, and merged my pull request soon afterwards. The fix is included in version 2.1.11, which is now published to NPM and available for use by the entire community. We are even using it now at Zocdoc!


Lessons Learned

The experience of encountering an unexpected error, discovering a bug in react-apollo, and contributing a fix back to the project taught me several lessons. First, I learned that even if I do not have much experience with a particular technology stack, digging deep to identify the root cause of a problem can be very fruitful. Second, I learned that it is relatively easy to contribute to open source projects like react-apollo that have active and supportive communities, especially if you’re willing to engage the community directly using their preferred communication channels for contribution. With Hacktoberfest under way, I’m keeping my eyes open for more opportunities like this to contribute to free, open-source tools. I use a lot of extremely helpful open source software at work but that I tend to take it for granted, so it’s nice to give back once in a while. Plus, contributing enough this month could result in a free t-shirt!


Mandatory picture of engineers pointing at code – from front to back: Anand Sundaram, Zack Banton, and Lucas Reis.

About the author

Anand Sundaram is a Software Engineer at Zocdoc. When he’s not at work, he’s probably reading: he enjoys reading both fiction and nonfiction, and recently finished Autobiography of Red by Anne Carson, which he really enjoyed.

No comments yet, be the first?

Close comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You might also like