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

Fully replace 'ApolloError' with 'GraphQLError' #6355

Merged

Conversation

IvanGoncharov
Copy link
Member

No description provided.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 25, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 250e9f2:

Sandbox Source
Apollo Server Typescript Configuration
Apollo Server Configuration

@IvanGoncharov
Copy link
Member Author

Big step toward #6053

packages/server/src/errors.ts Outdated Show resolved Hide resolved
packages/server/src/errors.ts Outdated Show resolved Hide resolved
packages/server/src/errors.ts Outdated Show resolved Hide resolved
Copy link
Member

@glasser glasser left a comment

Choose a reason for hiding this comment

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

Generally looks good! I'd like to see a bit more in the PR description (like say if there's any behavior lost by removing ApolloError, what things might come next, etc).

packages/server/src/errors.ts Outdated Show resolved Hide resolved
packages/server/src/errors.ts Show resolved Hide resolved
@IvanGoncharov IvanGoncharov force-pushed the removeApolloError branch 2 times, most recently from 8606699 to 847a5db Compare May 9, 2022 16:51
Copy link
Member

@glasser glasser left a comment

Choose a reason for hiding this comment

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

looking great!

packages/server/src/errors.ts Outdated Show resolved Hide resolved
// XXX: This cast is pretty sketchy, as other error types can be thrown!
return enrichError(err as Partial<GraphQLError>, debug);
if (includeStackTracesInErrorResponses) {
return enrichError(err);
Copy link
Member

Choose a reason for hiding this comment

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

This seems like the same as before and good logic but while reviewing this confusing code I think it could be made more clear.

Let's rename err to formattingError and call out explicitly "includeStackTracesInErrorResponses is used in development so it will be helpful to show errors thrown by formatError hooks in that mode". Though honestly maybe we should wrap the error in some sort of "error thrown in formatError hook" error?

Copy link
Member Author

Choose a reason for hiding this comment

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

Implemented your feedback.

Though honestly maybe we should wrap the error in some sort of "error thrown in formatError hook" error?

Not sure I need to think about it.
Maybe it's overkill but maybe not.


Object.defineProperty(this, 'name', { value: 'BadRequestError' });
this.name = 'BadRequestError';
}
}

// This function should not throw.
export function formatApolloErrors(
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a docstring that explains what this function actually does? I think it now is way more coherent then it used to be and the docstring might actually make sense!

IIUC it's:

  • Convert non-Error to Error
  • Convert non-GraphQLError to GraphQLError
  • Add a default extensions.code
  • This strange block that I don't 100% get the motivation of and would be great if it had a clear description: if (originalError != null && !(originalError instanceof GraphQLError))
  • Copy stack trace onto an extension if requested
  • Convert to GraphQLFormatterError
  • Pass through formatError if provided (doing some error handling if that throws)

Copy link
Member

Choose a reason for hiding this comment

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

Also before merging let's make sure the PR description has at least a brief list of all the changes that are made. Then we can flesh that out into the migration guide draft (which should be merged from #6453 soon) in a follow-up PR.

Copy link
Member

Choose a reason for hiding this comment

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

Also I think you said this but probably the function should get a better name since there are no more Apollo Errors. normalizeAndFormatErrors?

Copy link
Member Author

Choose a reason for hiding this comment

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

I like "enrich" more than "normalize" since we only add stuff and don't remove stuff.
formatError can remove stuff but it's more of "formating" part of this function.
enrichAndFormatErrors?

Copy link
Member

Choose a reason for hiding this comment

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

The normalize part to me is how we convert non-Error and non-GraphQLError to GraphQLError... but I see what you mean.

try {
return makePrintable(formatter(error));
return formatError(enrichError(error), error);
Copy link
Member

Choose a reason for hiding this comment

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

Interesting note: the change to two-arg formatError actually makes the fact that formatError is integrated into this function rather than just a second map over its output more crucial.
(ie, I was going to propose that (perhaps in a follow-up PR) we just remove this option and have the callers call formatError instead (or totally drop formatError and just have callers use didEncounterErrors from the plugin API) but this new argument makes the current structure make more sense.)

@IvanGoncharov
Copy link
Member Author

Just saw the code example in this article.
The new signature for API exactly matches provided code sample:
https://blog.escape.tech/graphql-error-handling-a-security-pov/#how-to-mask-sensitive-information-and-stack-traces

So it's independent proof that the new API is more intuitive.

expect(result.errors[0].extensions.code).toEqual('UNAUTHENTICATED');
expect(result.errors[0].extensions.ext1).toEqual('myExt');
expect(result.errors[0].extensions.exception).toBeDefined();
expect(result.errors[0].extensions.exception.ext1).toBeUndefined();
Copy link
Member

Choose a reason for hiding this comment

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

should we also check result.errors[0].extensions.exception.extensions is undefined? basically we want to make sure it isn't there twice. (Or we could just do an inline snapshot on result tbh)

@glasser
Copy link
Member

glasser commented Jun 2, 2022

(Approved though after merge this PR should be updated with a description of the changes.)

@IvanGoncharov IvanGoncharov merged commit 1f63af9 into apollographql:version-4 Jun 2, 2022
@IvanGoncharov IvanGoncharov deleted the removeApolloError branch June 2, 2022 16:47
@glasser glasser mentioned this pull request Jun 2, 2022
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jun 14, 2022
Implement fix proposed in apollographql#6558 but implement it on top of AS4
Also contain some cleanup and refactoring related to apollographql#6355
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jun 14, 2022
Implement fix proposed in apollographql#6558 but implement it on top of AS4
Also contain some cleanup and refactoring related to apollographql#6355
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jun 17, 2022
Implement fix proposed in apollographql#6558 but implement it on top of AS4
Also contain some cleanup and refactoring related to apollographql#6355
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jun 30, 2022
Implement fix proposed in apollographql#6558 but implement it on top of AS4
Also contain some cleanup and refactoring related to apollographql#6355
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jul 18, 2022
IvanGoncharov added a commit to IvanGoncharov/apollo-server that referenced this pull request Jul 18, 2022
glasser pushed a commit that referenced this pull request Jul 20, 2022
glasser added a commit that referenced this pull request Jul 22, 2022
* migration: start of an editing pass

* More progress on an editing pass

* make it build

* Reorganize and rework migration some more

* Apply suggestions from code review

Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com>

* migration: result of auditing the change in exported API

* migration: Add description of changes from #6355

* Reorganize error handling changes

* migration: gql tag

* Apply suggestions from code review

Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com>

* Tweak gql section

including re-adding triple-quotes because GH suggestions don't like
them. And I guess trimming trailing newlines which I guess my editor
does and which got introduced recently?

* Simplify some bullets and add body-parser/cors section back

* A few @trevor-scheer related changes

* Apply suggestions from code review

Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com>

* Follow-up to the previous one

* gateway

* as shown above

* context

Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com>
Co-authored-by: Ivan Goncharov <ivan.goncharov.ua@gmail.com>
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
…oError

This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
…2028)

This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
…2028)

This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
…2028)

This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.
glasser added a commit to apollographql/federation that referenced this pull request Aug 2, 2022
* gateway: remove dependency on apollo-server-caching (#2029)

The point of apollo-server-caching is to provide an abstraction over
multiple cache backends. Gateway is not using that abstraction; it's
just using one particular implementation, which is a wrapper around an
old version of lru-cache.

As part of apollographql/apollo-server#6057
and apollographql/apollo-server#6719 we want
to remove dependencies on Apollo Server from Apollo Gateway. Technically
we don't really need to remove this dependency (since
apollo-server-caching doesn't depend on anything else in AS) but
apollo-server-caching won't be updated any more (in fact, even in AS3 it
has already been replaced by `@apollo/utils.keyvaluecache`), so let's do
it.

While we're at it, we make a few other improvements:
- Ever since #440, the queryPlanStore field is always set, so we can
  remove some conditionals around it.
- Instead of using the old lru-cache@6 wrapped by the
  apollo-server-caching package, we use the newer lru-cache@7 (which
  improves the algorithm internally and changes the names of methods a
  bit).
- The get and set methods on InMemoryLRUCache were only async because
  they implement the abstract KeyValueCache interface: the
  implementations didn't actually do anything async. So we no longer
  need to await them or include a giant comment about how we're not
  awaiting them.

* gateway RemoteGraphQLDataSource: throw GraphQLError, not ApolloError (#2028)

This is part of
apollographql/apollo-server#6057 (which is
itself part of
apollographql/apollo-server#6719). We are
trying to break the dependency of Gateway on Server so that (among other
things) it is easier to have a single version of Gateway that works with
both the current AS3 and the upcoming AS4.

In AS4, we are removing the ApolloError class and its subclasses.
Instead, we will just use GraphQLError directly. See:

https://www.apollographql.com/docs/apollo-server/v4/migration#apolloerror
https://www.apollographql.com/docs/apollo-server/v4/migration#built-in-error-classes
apollographql/apollo-server#6355
apollographql/apollo-server#6705

This commit changes RemoteGraphQLDataSource to throw GraphQLError
instead of ApolloError. The `code` extension will still be the same.
(The `name` field of the thrown Error will no longer be eg
`AuthenticationError`, though; this does not affect the error as
serialized in GraphQL.)

This is technically slightly backwards-incompatible (eg, the method
errorFromResponse is public and now returns GraphQLError instead of the
tighter ApolloError) but this doesn't seem likely to affect many users.
We can adjust based on feedback if necessary.

* Adjust #2028 for graphql@15.8 compatibility
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 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.

None yet

3 participants