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

Assign unique error codes to production invariant errors. #4521

Merged
merged 2 commits into from
Mar 4, 2019

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Mar 2, 2019

Should help address #4519.

Implemented and explained by apollographql/invariant-packages#1.

Copy link
Member

@hwillson hwillson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff - thanks @benjamn!

// location), which makes it much easier to trace production
// errors back to the unminified code where they were thrown,
// where the full error string can be found. See #4519.
errorCodes: true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Would it be possible for the error codes to be there in both the production and development versions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error codes will be present in Apollo Client library code in development, since the unminified code looks like this:

process.env.NODE_ENV === 'production'
  ? invariant(condition, <error code>)
  : invariant(condition, message)

The codes won't be automatically included in the error messages in development, though. I think this is a reasonable balance, since these error codes are subject to change, so we don't want to commit to specific numbers for specific errors. The goal of this PR is just to make sure it's possible to make sense of production errors.

@benjamn benjamn force-pushed the assign-numeric-codes-to-invariant-errors branch from 3081ba2 to d668ca4 Compare March 4, 2019 16:37
@benjamn benjamn merged commit 251b14e into master Mar 4, 2019
@benjamn benjamn deleted the assign-numeric-codes-to-invariant-errors branch March 4, 2019 16:50
@skuridin
Copy link

skuridin commented Jul 3, 2019

@benjamn is there a way to decode these numbers without knowing the apollo-client codebase?

Invariant Violation: 10

I don't even know where to start.

@rshk
Copy link

rshk commented Jul 12, 2019

@skuridin best way I found so far is running:

grep -r invariant node_modules/**/bundle.cjs.js

Then try and guess which package actually raised the invariant error (error codes are unique per package, not globally).


May I ask what's the rationale behind this btw? (hiding error messages in production). Doesn't seem like something that actually needs to be kept secret from the client? And doesn't seem to be improving performance either.

@toddtarsi
Copy link

@rshk - This doesn't work all of the time. I recently tried with a development build, looking for a code 14. Nothing. Skipped right over 14. There was a 13 and 15, but no 14 like we're seeing in production. 😦

@benjamn
Copy link
Member Author

benjamn commented Aug 1, 2019

Did you try searching for both invariant and InvariantError?

@rshk This has been one of the more effective ways of reducing bundle sizes, since those error strings can be long and they do not minify.

@toddtarsi
Copy link

toddtarsi commented Aug 1, 2019

@benjamn - THERE IT IS! 🤦‍♂ You are right. Thank you sir. I'll delete my comment on the other thread.

To note everyone, I was missing my error, but this resolved that:

grep -r InvariantError node_modules/**/bundle.cjs.js

@nosovsh
Copy link

nosovsh commented Sep 12, 2019

Any possibility to determine the error type dynamically?
e.g. fetchMore doesn't have the possibility to cancel request, so if your component gets unmounted while request is still executing you will get "Invariant Violation: ObservableQuery with this id doesn't exist: XX" in development mode or "Invariant Violation: 17" in production.

Since this error is not really a "error" I don't want it to appear in logs so I want to put fetchMore in "try...catch" and suppress there, but I don't want to accidentally suppress some other error. I can not do e.message === "Invariant Violation: 17" since 17 can change with the next build.

So my question whether it is possible to know that code "17" corresponds to "ObservableQuery with this id doesn't exist" in code and not with grep

@Grohden
Copy link

Grohden commented Jan 23, 2020

It's really frustrating. Invariant error codes can be repeated in packages, so without sourcemaps we can't tell which error is actually happening.

➜  keepfy-app git:(testing/codepush) ✗ grep -r "InvariantError(8)" node_modules/**/bundle.cjs.js
node_modules/apollo-cache-inmemory/lib/bundle.cjs.js:        throw process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(8) : new _tsInvariant.InvariantError("Can't find field " + info.fieldName + " on object " + JSON.stringify(info.object, null, 2) + ".");
node_modules/apollo-client/bundle.cjs.js:      reject(process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(8) : new _tsInvariant.InvariantError('QueryManager stopped while query was in flight'));

And why the URL doesn't point to some place useful like a doc or something?
Network error: Invariant Violation: 8 (see https://github.com/apollographql/invariant-packages)

It's not helpful at all to point to invariant-packages repo.

@benjamn
Copy link
Member Author

benjamn commented Jan 23, 2020

@Grohden There's an explanation of error codes in the README.md of that repository.

@Grohden
Copy link

Grohden commented Jan 23, 2020

@benjamn I mean 'doc or something' like a place where the codes are documented (well, technically, they're documented on the code, but multiple packages with same code makes this unhelpful)... anyway, invariant could point which package is triggering this (force some the package to inform it maybe?), then the grep multiple return wouldn't be a problem.

Maybe add an anchor (https://github.com/apollographql/invariant-packages#error-codes) and document a way about how to find the error codes (eg: grep) could make things better...

@toddtarsi
Copy link

toddtarsi commented Feb 14, 2020

@benjamn - This is definitely falling apart as a method. Deliberate codes are needed here. Invariant codes are no longer matching up, even when using the same method. If your error codes only work with source maps live, you have a problem.

To provide a little more context, I have a fixed version of Apollo Client, but when I build locally vs when I build in an environment like AWS Codebuild, things stop matching. One environment matches the error up with code 19, and one environment may match the error up with code 10.

As a result, the only way I can truly match up an error in ApolloClient is to reproduce the error in dev. It's very disappointing.

@toddtarsi
Copy link

@benjamn - Nevermind, I'm an idiot. I'm looking at your invariant stuff, and it seems pretty much 1:1 with how react does stuff. I'm just flustered and confused. Somehow I was getting an error code that matched up with 19 in my staging environment, something about an invalid string or something having to do with SSR. I built locally, assuming everything was going to be the same since they're on the same version. However, when I ran it locally in dev, the error was about using an invalid fetchPolicy for mutations, and I checked where this was in the codebase, and it matched up with error code 10. I don't know why something like that would occur, and it frankly scares the willies out of me. I need to get my source maps working again >_<

benjamn added a commit that referenced this pull request Jul 21, 2020
When an invariant fails in production, a cryptic numeric error of the form
`Invariant Violation: 42` is thrown, with a reference to the error codes
section of invariant-packages README.md: https://github.com/apollographql/invariant-packages#error-codes

This vague guidance has not proven adequate in many cases, to say the
least: see apollographql/invariant-packages#18,
apollographql/invariant-packages#19, #6604,

However, this vague guidance (which was intended to suggest searching
your installed node_modules/@apollo/client package for the error code)
has not proven adequate in many cases, to say the least: see apollographql/invariant-packages#18,
apollographql/invariant-packages#19, #6604, #5730, #5291, and #5975,
to cite just a few of the many issues we've seen since #4521.

Using error codes instead of error strings remains important for
production bundle sizes, but I think we can make it substantially easier
to look up the error string corresponding to each error code, by
generating a single file containing all the invariant error codes for each
@apollo/client release.

Starting with Apollo Client 3.1.0, this manifest file can be found in
@apollo/client/invariantErrorCodes.js (using an npm/yarn-installed copy of
@apollo/client, since this file is generated in the ./dist directory, not
checked into the repository). The file contains an explanatory comment,
the @apollo/client version, and a sequential map from error numbers to the
{ file, node } responsible for the error.
jimrandomh pushed a commit to jimrandomh/apollo-client that referenced this pull request Jul 22, 2020
…llographql#6665)

When an invariant fails in production, a cryptic numeric error of the form
`Invariant Violation: 42` is thrown, with a reference to the error codes
section of invariant-packages README.md: https://github.com/apollographql/invariant-packages#error-codes

This vague guidance has not proven adequate in many cases, to say the
least: see apollographql/invariant-packages#18,
apollographql/invariant-packages#19, apollographql#6604,

However, this vague guidance (which was intended to suggest searching
your installed node_modules/@apollo/client package for the error code)
has not proven adequate in many cases, to say the least: see apollographql/invariant-packages#18,
apollographql/invariant-packages#19, apollographql#6604, apollographql#5730, apollographql#5291, and apollographql#5975,
to cite just a few of the many issues we've seen since apollographql#4521.

Using error codes instead of error strings remains important for
production bundle sizes, but I think we can make it substantially easier
to look up the error string corresponding to each error code, by
generating a single file containing all the invariant error codes for each
@apollo/client release.

Starting with Apollo Client 3.1.0, this manifest file can be found in
@apollo/client/invariantErrorCodes.js (using an npm/yarn-installed copy of
@apollo/client, since this file is generated in the ./dist directory, not
checked into the repository). The file contains an explanatory comment,
the @apollo/client version, and a sequential map from error numbers to the
{ file, node } responsible for the error.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants