@apollo/federation-internals
Advanced tools
Comparing version 2.0.0-preview.3 to 2.0.0-preview.4
@@ -9,2 +9,6 @@ # CHANGELOG for `@apollo/federation-internals` | ||
## v2.0.0-preview.4 | ||
- Make error messages more actionable when constructing subgraphs from a supergraph [PR #1586](https://github.com/apollographql/federation/pull/1586) | ||
## v2.0.0-preview.3 | ||
@@ -11,0 +15,0 @@ |
@@ -214,8 +214,8 @@ "use strict"; | ||
if (isFed1) { | ||
const msg = `Error extracting subgraph ${subgraph.name} from the supergraph: this might due to errors in subgraphs that were mistakenly ignored by federation 0.x versions but are rejected by federation 2.\n` | ||
+ 'Please try composing your subgraphs with federation 2: this should help precisely pinpoint the errors and generate a correct federation 2 supergraph.'; | ||
const msg = `Error extracting subgraph "${subgraph.name}" from the supergraph: this might be due to errors in subgraphs that were mistakenly ignored by federation 0.x versions but are rejected by federation 2.\n` | ||
+ 'Please try composing your subgraphs with federation 2: this should help precisely pinpoint the problems and, once fixed, generate a correct federation 2 supergraph'; | ||
throw new Error(`${msg}.\n\nDetails:\n${errorToString(e)}`); | ||
} | ||
else { | ||
const msg = `Unexpected error extracting subgraph ${subgraph.name} from the supergraph: this is either a bug, or the supergraph has been corrupted.`; | ||
const msg = `Unexpected error extracting subgraph ${subgraph.name} from the supergraph: this is either a bug, or the supergraph has been corrupted`; | ||
const dumpMsg = maybeDumpSubgraphSchema(subgraph); | ||
@@ -351,3 +351,7 @@ throw new Error(`${msg}.\n\nDetails:\n${errorToString(e)}\n\n${dumpMsg}`); | ||
}; | ||
(0, federation_1.parseFieldSetArgument)({ parentType, directive, fieldAccessor }); | ||
try { | ||
(0, federation_1.parseFieldSetArgument)({ parentType, directive, fieldAccessor, validate: false }); | ||
} | ||
catch (e) { | ||
} | ||
} | ||
@@ -354,0 +358,0 @@ function addExternalFieldsFromInterface(metadata, type) { |
{ | ||
"name": "@apollo/federation-internals", | ||
"version": "2.0.0-preview.3", | ||
"version": "2.0.0-preview.4", | ||
"description": "Apollo Federation internal utilities", | ||
@@ -36,3 +36,3 @@ "main": "dist/index.js", | ||
}, | ||
"gitHead": "238ff9edebda4af3c247b4073dce7e4f2a86e3c1" | ||
"gitHead": "1ab3c3b872dade5ca564bd3ba3ac723a99ad4960" | ||
} |
@@ -536,1 +536,65 @@ import { buildSupergraphSchema, extractSubgraphsFromSupergraph } from ".."; | ||
}) | ||
test('throw meaningful error for invalid federation directive fieldSet', () => { | ||
const supergraph = ` | ||
schema | ||
@core(feature: "https://specs.apollo.dev/core/v0.2"), | ||
@core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) | ||
{ | ||
query: Query | ||
} | ||
directive @core(as: String, feature: String!, for: core__Purpose) repeatable on SCHEMA | ||
directive @join__field(graph: join__Graph, provides: join__FieldSet, requires: join__FieldSet) on FIELD_DEFINITION | ||
directive @join__graph(name: String!, url: String!) on ENUM_VALUE | ||
directive @join__owner(graph: join__Graph!) on INTERFACE | OBJECT | ||
directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on INTERFACE | OBJECT | ||
type A @join__owner(graph: SERVICEA) @join__type(graph: SERVICEA, key: "id") @join__type(graph: SERVICEB, key: "id") { | ||
id: ID | ||
a: Int @join__field(graph: SERVICEB, requires: "b { x }") | ||
b: B | ||
} | ||
type B @join__owner(graph: SERVICEA) @join__type(graph: SERVICEA, key: "id") { | ||
id: ID | ||
x: Int | ||
} | ||
type Query { | ||
q: A | ||
} | ||
enum core__Purpose { | ||
""" | ||
\`EXECUTION\` features provide metadata necessary to for operation execution. | ||
""" | ||
EXECUTION | ||
""" | ||
\`SECURITY\` features provide metadata necessary to securely resolve fields. | ||
""" | ||
SECURITY | ||
} | ||
scalar join__FieldSet | ||
enum join__Graph { | ||
SERVICEA @join__graph(name: "serviceA" url: "") | ||
SERVICEB @join__graph(name: "serviceB" url: "") | ||
} | ||
`; | ||
const schema = buildSupergraphSchema(supergraph)[0]; | ||
expect(() => extractSubgraphsFromSupergraph(schema)).toThrow( | ||
'Error extracting subgraph "serviceB" from the supergraph: this might be due to errors in subgraphs that were mistakenly ignored by federation 0.x versions but are rejected by federation 2.\n' | ||
+ 'Please try composing your subgraphs with federation 2: this should help precisely pinpoint the problems and, once fixed, generate a correct federation 2 supergraph.\n' | ||
+ '\n' | ||
+ 'Details:\n' | ||
+ '[serviceB] On field "A.a", for @requires(fields: "b { x }"): Cannot query field "b" on type "A" (if the field is defined in another subgraph, you need to add it to this subgraph with @external).' | ||
); | ||
}) |
@@ -295,7 +295,7 @@ import { | ||
// it'll solve the issue and that's good, or we'll hit the other message anyway. | ||
const msg = `Error extracting subgraph ${subgraph.name} from the supergraph: this might due to errors in subgraphs that were mistakenly ignored by federation 0.x versions but are rejected by federation 2.\n` | ||
+ 'Please try composing your subgraphs with federation 2: this should help precisely pinpoint the errors and generate a correct federation 2 supergraph.'; | ||
const msg = `Error extracting subgraph "${subgraph.name}" from the supergraph: this might be due to errors in subgraphs that were mistakenly ignored by federation 0.x versions but are rejected by federation 2.\n` | ||
+ 'Please try composing your subgraphs with federation 2: this should help precisely pinpoint the problems and, once fixed, generate a correct federation 2 supergraph'; | ||
throw new Error(`${msg}.\n\nDetails:\n${errorToString(e)}`); | ||
} else { | ||
const msg = `Unexpected error extracting subgraph ${subgraph.name} from the supergraph: this is either a bug, or the supergraph has been corrupted.`; | ||
const msg = `Unexpected error extracting subgraph ${subgraph.name} from the supergraph: this is either a bug, or the supergraph has been corrupted`; | ||
const dumpMsg = maybeDumpSubgraphSchema(subgraph); | ||
@@ -483,3 +483,15 @@ throw new Error(`${msg}.\n\nDetails:\n${errorToString(e)}\n\n${dumpMsg}`); | ||
}; | ||
parseFieldSetArgument({parentType, directive, fieldAccessor}); | ||
try { | ||
parseFieldSetArgument({parentType, directive, fieldAccessor, validate: false}); | ||
} catch (e) { | ||
// Ignored on purpose: for fed1 supergraphs, it's possible that some of the fields defined in a federation directive | ||
// was _not_ defined in the subgraph because fed1 was not validating this properly (the validation wasn't handling | ||
// nested fields as it should), which may result in an error when trying to add those as an external field. | ||
// However, this is not the right place to throw. Instead, we ignore the problem and thus exit without having added | ||
// all the necessary fields, and so this very same directive will fail validation at the end of the extraction when | ||
// we do the final validation of the extracted subgraph (see end of `extractSubgraphsFromSupergraph`). And we prefer | ||
// failing then because 1) that later validation will collect all errors instead of failing on the first one and | ||
// 2) we already have special error messages and the ability to dump the extracted subgraphs for debug at that point, | ||
// so it's a much better place. | ||
} | ||
} | ||
@@ -486,0 +498,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1416210
23052