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

fix(gateway): Ignore thrown errors from extendSchema #478

Merged
merged 5 commits into from
Feb 26, 2021

Conversation

trevor-scheer
Copy link
Member

@trevor-scheer trevor-scheer commented Feb 25, 2021

extendSchema throws errors in the case that we extend a type before it exists during composition. This should certainly result in composition errors (which we have validations for), but it shouldn't cause composeAndValidate to throw, which is unexpected.

This change catches and discards errors thrown by extendSchema. The reason for discarding and not capturing the error (Unknown type Bar.) is that it's duplicated when we capture errors from validateSDL immediately after: https://github.com/apollographql/federation/blob/8f77bf41d8c5075ee1b5de6d7018a70326f39acd/federation-js/src/composition/compose.ts#L421

In the extendSchema code path, there is only one throw case (excluding an initial assertSchema which I'm not concerned about) and this test case exercises it. However, I'm unsure about this approach because there could be other errors thrown in the future which may be valuable or worth capturing. Open to feedback here, or possibly an alternative solution.

Bit of an unrelated tangent here, but worth mentioning:
Modifying this area of the codebase made it tempting to return as early as possible once all errors are collected and stop returning both a schema and errors (which seems like odd behavior). However, we can provide more errors to the user when compose returns both, since composeAndValidate can take composition errors and append useful schema validation errors to the final set of errors provided.

It wouldn't be unreasonable at some point to stop returning both a schema and errors from composeAndValidate, however (this is already what we do with composedSdl).

@@ -514,6 +523,7 @@ export function addFederationMetadataToSchemaNodes({
// TODO: Why don't we need to check for non-object types here
if (isObjectType(namedType)) {
const field = namedType.getFields()[fieldName];
if (!field) break;
Copy link
Member Author

Choose a reason for hiding this comment

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

As seen here in the new test case, when a type goes unrecognized, fields which return that type are abandoned. This handles the case where a field which is expected to exist cannot actually be found in the schema.

@martijnwalraven
Copy link
Contributor

martijnwalraven commented Feb 26, 2021

I think this is indeed a bit of an unconventional use of the graphql-js APIs. We're telling extendSchema to skip validating the passed in SDL, while we may actually have captured validation errors on the previous line through validateSDL. It isn't great to ignore errors, but I think the error that's being thrown would never occur under normal circumstances, because errors should be caught by validation (either in validateSDL or validateSchema). So for now, this seems like the best we can do. (I agree it may make sense to fail early instead, although that would keep us from reporting additional errors.)

That does make me wonder if we shouldn't also collect errors resulting from validateSchema in composeAndValidate (in addition to collecting errors from validateSDL). I don't have a good sense of what additional errors that might catch (and whether those are relevant for our use case), but extendSchema has quite a few comments that state they purposefully avoid throwing errors early because these will be caught by validateSchema later and that can provide more meaningful feedback.

@trevor-scheer trevor-scheer force-pushed the trevor/capture-composition-errors branch from dcd9a9c to 5f320ee Compare February 26, 2021 15:26
@trevor-scheer trevor-scheer merged commit 2474d14 into main Feb 26, 2021
@trevor-scheer trevor-scheer deleted the trevor/capture-composition-errors branch February 26, 2021 16:30
@@ -514,6 +523,7 @@ export function addFederationMetadataToSchemaNodes({
// TODO: Why don't we need to check for non-object types here
if (isObjectType(namedType)) {
const field = namedType.getFields()[fieldName];
if (!field) break;
Copy link
Member Author

Choose a reason for hiding this comment

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

break was a mistake here, but corrected in #481

@glasser
Copy link
Member

glasser commented Feb 26, 2021

I suggested to Trevor on Slack that we do something more like

try {
  extendSchema()
} catch (e) {
  if (e is not the one particular error we know we handle later) {
    throw Error("extendSchema threw an unexpected error type", e)  // or add to the errors list maybe
  }
}

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

Successfully merging this pull request may close these issues.

3 participants