-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Fully replace 'ApolloError' with 'GraphQLError' #6355
Conversation
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:
|
Big step toward #6053 |
There was a problem hiding this 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).
8606699
to
847a5db
Compare
There was a problem hiding this 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
// 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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.)
14369e5
to
79640b8
Compare
Based on @glasser review suggestion
6ad20f1
to
972b05b
Compare
Just saw the code example in this article. 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(); |
There was a problem hiding this comment.
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)
(Approved though after merge this PR should be updated with a description of the changes.) |
Implement fix proposed in apollographql#6558 but implement it on top of AS4 Also contain some cleanup and refactoring related to apollographql#6355
Implement fix proposed in apollographql#6558 but implement it on top of AS4 Also contain some cleanup and refactoring related to apollographql#6355
Implement fix proposed in apollographql#6558 but implement it on top of AS4 Also contain some cleanup and refactoring related to apollographql#6355
Implement fix proposed in apollographql#6558 but implement it on top of AS4 Also contain some cleanup and refactoring related to apollographql#6355
* 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 <[email protected]> * 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 <[email protected]> * Apply suggestions from code review Co-authored-by: Rose M Koron <[email protected]> * 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 <[email protected]> * Follow-up to the previous one * gateway * as shown above * context Co-authored-by: Rose M Koron <[email protected]> Co-authored-by: Ivan Goncharov <[email protected]>
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.
…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.
…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.
* 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 [email protected] compatibility
No description provided.