1pub(crate) mod suggestion;
2
3use std::cmp::Ordering;
4use std::fmt::Display;
5use std::fmt::Formatter;
6use std::fmt::Write;
7use std::ops::Range;
8use std::sync::LazyLock;
9
10use apollo_compiler::InvalidNameError;
11use apollo_compiler::Name;
12use apollo_compiler::ast::OperationType;
13use apollo_compiler::parser::LineColumn;
14use apollo_compiler::validation::DiagnosticList;
15use apollo_compiler::validation::WithErrors;
16
17use crate::subgraph::SubgraphError;
18use crate::subgraph::spec::FederationSpecError;
19use crate::subgraph::typestate::HasMetadata;
20use crate::subgraph::typestate::Subgraph;
21
22#[macro_export]
35macro_rules! internal_error {
36 ( $( $arg:tt )+ ) => {
37 $crate::error::FederationError::internal(format!( $( $arg )+ ))
38 }
39}
40
41#[macro_export]
57macro_rules! bail {
58 ( $( $arg:tt )+ ) => {
59 return Err($crate::internal_error!( $( $arg )+ ).into())
60 }
61}
62
63#[macro_export]
81macro_rules! ensure {
82 ( $expr:expr, $( $arg:tt )+ ) => {
83 #[cfg(debug_assertions)]
84 {
85 if false {
86 return Err($crate::error::FederationError::internal("ensure!() must be used in a function that returns a Result").into());
87 }
88 assert!($expr, $( $arg )+);
89 }
90
91 #[cfg(not(debug_assertions))]
92 if !$expr {
93 $crate::bail!( $( $arg )+ );
94 }
95 }
96}
97
98#[derive(Clone, Debug, strum_macros::Display)]
101enum SchemaRootKind {
102 #[strum(to_string = "query")]
103 Query,
104 #[strum(to_string = "mutation")]
105 Mutation,
106 #[strum(to_string = "subscription")]
107 Subscription,
108}
109
110impl From<SchemaRootKind> for String {
111 fn from(value: SchemaRootKind) -> Self {
112 value.to_string()
113 }
114}
115
116#[derive(Clone, Debug, strum_macros::Display, PartialEq, Eq)]
117pub enum UnsupportedFeatureKind {
118 #[strum(to_string = "alias")]
119 Alias,
120}
121
122#[derive(Clone, Debug)]
125pub struct SubgraphLocation {
126 pub subgraph: String, pub range: Range<LineColumn>,
130}
131
132pub type Locations = Vec<SubgraphLocation>;
133
134pub(crate) trait HasLocations {
135 fn locations<T: HasMetadata>(&self, subgraph: &Subgraph<T>) -> Locations;
136}
137
138#[derive(Debug, Clone, thiserror::Error)]
139pub enum CompositionError {
140 #[error("[{subgraph}] {error}")]
141 SubgraphError {
142 subgraph: String,
143 error: SingleFederationError,
144 locations: Locations,
145 },
146 #[error("{message}")]
147 ContextualArgumentNotContextualInAllSubgraphs {
148 message: String,
149 locations: Locations,
150 },
151 #[error("{message}")]
152 EmptyMergedEnumType {
153 message: String,
154 locations: Locations,
155 },
156 #[error("{message}")]
157 EnumValueMismatch { message: String },
158 #[error("{message}")]
159 ExternalArgumentTypeMismatch { message: String },
160 #[error("{message}")]
161 ExternalTypeMismatch { message: String },
162 #[error("{message}")]
163 ExternalArgumentDefaultMismatch { message: String },
164 #[error("{message}")]
165 InvalidGraphQL { message: String },
166 #[error(transparent)]
167 InvalidGraphQLName(InvalidNameError),
168 #[error(r#"{message} in @fromContext substring "{context}""#)]
169 FromContextParseError { context: String, message: String },
170 #[error(
171 "Unsupported custom directive @{name} on fragment spread. Due to query transformations during planning, the router requires directives on fragment spreads to support both the FRAGMENT_SPREAD and INLINE_FRAGMENT locations."
172 )]
173 UnsupportedSpreadDirective { name: Name },
174 #[error("{message}")]
175 DirectiveDefinitionInvalid { message: String },
176 #[error("{message}")]
177 TypeDefinitionInvalid { message: String },
178 #[error("{message}")]
179 InterfaceObjectUsageError { message: String },
180 #[error("{message}")]
181 InterfaceKeyMissingImplementationType { message: String },
182 #[error("{message}")]
183 TypeKindMismatch { message: String },
184 #[error("{message}")]
185 ShareableHasMismatchedRuntimeTypes { message: String },
186 #[error("{message}")]
187 SatisfiabilityError { message: String },
188 #[error("{message}")]
189 MaxValidationSubgraphPathsExceeded { message: String },
190 #[error("{message}")]
191 InternalError { message: String },
192 #[error("{message}")]
193 ExternalArgumentMissing { message: String },
194 #[error("{message}")]
195 ExternalMissingOnBase { message: String },
196 #[error("{message}")]
197 MergedDirectiveApplicationOnExternal { message: String },
198 #[error("{message}")]
199 LinkImportNameMismatch { message: String },
200 #[error("{message}")]
201 InvalidFieldSharing {
202 message: String,
203 locations: Locations,
204 },
205 #[error(
206 "[{subgraph}] Type \"{dest}\" is an extension type, but there is no type definition for \"{dest}\" in any subgraph."
207 )]
208 ExtensionWithNoBase {
209 subgraph: String,
210 dest: String,
211 locations: Locations,
212 },
213 #[error("{message}")]
214 DirectiveCompositionError { message: String },
215 #[error("{message}")]
216 InconsistentInputObjectField { message: String },
217 #[error("{message}")]
218 RequiredArgumentMissingInSomeSubgraph {
219 message: String,
220 locations: Locations,
221 },
222 #[error("{message}")]
223 RequiredInputFieldMissingInSomeSubgraph {
224 message: String,
225 locations: Locations,
226 },
227 #[error("{message}")]
228 EmptyMergedInputType {
229 message: String,
230 locations: Locations,
231 },
232 #[error("{message}")]
233 InputFieldMergeFailed {
234 message: String,
235 locations: Locations,
236 },
237 #[error("{message}")]
238 FieldArgumentTypeMismatch { message: String },
239 #[error("{message}")]
240 FieldTypeMismatch { message: String },
241 #[error("{message}")]
242 OverrideCollisionWithAnotherDirective { message: String },
243 #[error("{message}")]
244 OverrideFromSelfError { message: String },
245 #[error("{message}")]
246 OverrideLabelInvalid { message: String },
247 #[error("{message}")]
248 OverrideOnInterface { message: String },
249 #[error("{message}")]
250 OverrideSourceHasOverride { message: String },
251 #[error("{message}")]
252 QueryRootMissing { message: String },
253 #[error("{message}")]
254 ArgumentDefaultMismatch {
255 message: String,
256 locations: Locations,
257 },
258 #[error("{message}")]
259 InputFieldDefaultMismatch {
260 message: String,
261 locations: Locations,
262 },
263}
264
265impl CompositionError {
266 pub fn code(&self) -> ErrorCode {
267 match self {
268 Self::SubgraphError { error, .. } => error.code(),
269 Self::ContextualArgumentNotContextualInAllSubgraphs { .. } => {
270 ErrorCode::ContextualArgumentNotContextualInAllSubgraphs
271 }
272 Self::EmptyMergedEnumType { .. } => ErrorCode::EmptyMergedEnumType,
273 Self::EnumValueMismatch { .. } => ErrorCode::EnumValueMismatch,
274 Self::ExternalTypeMismatch { .. } => ErrorCode::ExternalTypeMismatch,
275 Self::ExternalArgumentTypeMismatch { .. } => ErrorCode::ExternalArgumentTypeMismatch,
276 Self::ExternalArgumentDefaultMismatch { .. } => {
277 ErrorCode::ExternalArgumentDefaultMismatch
278 }
279 Self::InvalidGraphQL { .. } => ErrorCode::InvalidGraphQL,
280 Self::InvalidGraphQLName(..) => ErrorCode::InvalidGraphQL,
281 Self::FromContextParseError { .. } => ErrorCode::InvalidGraphQL,
282 Self::UnsupportedSpreadDirective { .. } => ErrorCode::InvalidGraphQL,
283 Self::DirectiveDefinitionInvalid { .. } => ErrorCode::DirectiveDefinitionInvalid,
284 Self::TypeDefinitionInvalid { .. } => ErrorCode::TypeDefinitionInvalid,
285 Self::InterfaceObjectUsageError { .. } => ErrorCode::InterfaceObjectUsageError,
286 Self::InterfaceKeyMissingImplementationType { .. } => {
287 ErrorCode::InterfaceKeyMissingImplementationType
288 }
289 Self::TypeKindMismatch { .. } => ErrorCode::TypeKindMismatch,
290 Self::ShareableHasMismatchedRuntimeTypes { .. } => {
291 ErrorCode::ShareableHasMismatchedRuntimeTypes
292 }
293 Self::SatisfiabilityError { .. } => ErrorCode::SatisfiabilityError,
294 Self::MaxValidationSubgraphPathsExceeded { .. } => {
295 ErrorCode::MaxValidationSubgraphPathsExceeded
296 }
297 Self::InternalError { .. } => ErrorCode::Internal,
298 Self::ExternalArgumentMissing { .. } => ErrorCode::ExternalArgumentMissing,
299 Self::ExternalMissingOnBase { .. } => ErrorCode::ExternalMissingOnBase,
300 Self::MergedDirectiveApplicationOnExternal { .. } => {
301 ErrorCode::MergedDirectiveApplicationOnExternal
302 }
303 Self::LinkImportNameMismatch { .. } => ErrorCode::LinkImportNameMismatch,
304 Self::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
305 Self::InconsistentInputObjectField { .. } => ErrorCode::Internal, Self::RequiredArgumentMissingInSomeSubgraph { .. } => {
307 ErrorCode::RequiredArgumentMissingInSomeSubgraph
308 }
309 Self::RequiredInputFieldMissingInSomeSubgraph { .. } => {
310 ErrorCode::RequiredInputFieldMissingInSomeSubgraph
311 }
312 Self::EmptyMergedInputType { .. } => ErrorCode::EmptyMergedInputType,
313 Self::InputFieldMergeFailed { .. } => ErrorCode::InputFieldMergeFailed,
314 Self::ExtensionWithNoBase { .. } => ErrorCode::ExtensionWithNoBase,
315 Self::DirectiveCompositionError { .. } => ErrorCode::DirectiveCompositionError,
316 Self::FieldArgumentTypeMismatch { .. } => ErrorCode::FieldArgumentTypeMismatch,
317 Self::FieldTypeMismatch { .. } => ErrorCode::FieldTypeMismatch,
318 Self::OverrideCollisionWithAnotherDirective { .. } => {
319 ErrorCode::OverrideCollisionWithAnotherDirective
320 }
321 Self::OverrideFromSelfError { .. } => ErrorCode::OverrideFromSelfError,
322 Self::OverrideLabelInvalid { .. } => ErrorCode::OverrideLabelInvalid,
323 Self::OverrideOnInterface { .. } => ErrorCode::OverrideOnInterface,
324 Self::OverrideSourceHasOverride { .. } => ErrorCode::OverrideSourceHasOverride,
325 Self::QueryRootMissing { .. } => ErrorCode::QueryRootMissing,
326 Self::ArgumentDefaultMismatch { .. } => ErrorCode::FieldArgumentDefaultMismatch,
327 Self::InputFieldDefaultMismatch { .. } => ErrorCode::InputFieldDefaultMismatch,
328 }
329 }
330
331 pub(crate) fn append_message(self, appendix: impl Display) -> Self {
332 match self {
333 Self::EmptyMergedEnumType { message, locations } => Self::EmptyMergedEnumType {
334 message: format!("{message}{appendix}"),
335 locations,
336 },
337 Self::EnumValueMismatch { message } => Self::EnumValueMismatch {
338 message: format!("{message}{appendix}"),
339 },
340 Self::ExternalTypeMismatch { message } => Self::ExternalTypeMismatch {
341 message: format!("{message}{appendix}"),
342 },
343 Self::ExternalArgumentTypeMismatch { message } => Self::ExternalArgumentTypeMismatch {
344 message: format!("{message}{appendix}"),
345 },
346 Self::ExternalArgumentDefaultMismatch { message } => {
347 Self::ExternalArgumentDefaultMismatch {
348 message: format!("{message}{appendix}"),
349 }
350 }
351 Self::InvalidGraphQL { message } => Self::InvalidGraphQL {
352 message: format!("{message}{appendix}"),
353 },
354 Self::DirectiveDefinitionInvalid { message } => Self::DirectiveDefinitionInvalid {
355 message: format!("{message}{appendix}"),
356 },
357 Self::TypeDefinitionInvalid { message } => Self::TypeDefinitionInvalid {
358 message: format!("{message}{appendix}"),
359 },
360 Self::InterfaceObjectUsageError { message } => Self::InterfaceObjectUsageError {
361 message: format!("{message}{appendix}"),
362 },
363 Self::InterfaceKeyMissingImplementationType { message } => {
364 Self::InterfaceKeyMissingImplementationType {
365 message: format!("{message}{appendix}"),
366 }
367 }
368 Self::TypeKindMismatch { message } => Self::TypeKindMismatch {
369 message: format!("{message}{appendix}"),
370 },
371 Self::ShareableHasMismatchedRuntimeTypes { message } => {
372 Self::ShareableHasMismatchedRuntimeTypes {
373 message: format!("{message}{appendix}"),
374 }
375 }
376 Self::SatisfiabilityError { message } => Self::SatisfiabilityError {
377 message: format!("{message}{appendix}"),
378 },
379 Self::MaxValidationSubgraphPathsExceeded { message } => {
380 Self::MaxValidationSubgraphPathsExceeded {
381 message: format!("{message}{appendix}"),
382 }
383 }
384 Self::InternalError { message } => Self::InternalError {
385 message: format!("{message}{appendix}"),
386 },
387 Self::ExternalArgumentMissing { message } => Self::ExternalArgumentMissing {
388 message: format!("{message}{appendix}"),
389 },
390 Self::ExternalMissingOnBase { message } => Self::ExternalMissingOnBase {
391 message: format!("{message}{appendix}"),
392 },
393 Self::MergedDirectiveApplicationOnExternal { message } => {
394 Self::MergedDirectiveApplicationOnExternal {
395 message: format!("{message}{appendix}"),
396 }
397 }
398 Self::LinkImportNameMismatch { message } => Self::LinkImportNameMismatch {
399 message: format!("{message}{appendix}"),
400 },
401 Self::InvalidFieldSharing { message, locations } => Self::InvalidFieldSharing {
402 message: format!("{message}{appendix}"),
403 locations,
404 },
405 Self::DirectiveCompositionError { message } => Self::DirectiveCompositionError {
406 message: format!("{message}{appendix}"),
407 },
408 Self::InconsistentInputObjectField { message } => Self::InconsistentInputObjectField {
409 message: format!("{message}{appendix}"),
410 },
411 Self::RequiredArgumentMissingInSomeSubgraph { message, locations } => {
412 Self::RequiredArgumentMissingInSomeSubgraph {
413 message: format!("{message}{appendix}"),
414 locations,
415 }
416 }
417 Self::RequiredInputFieldMissingInSomeSubgraph { message, locations } => {
418 Self::RequiredInputFieldMissingInSomeSubgraph {
419 message: format!("{message}{appendix}"),
420 locations,
421 }
422 }
423 Self::EmptyMergedInputType { message, locations } => Self::EmptyMergedInputType {
424 message: format!("{message}{appendix}"),
425 locations,
426 },
427 Self::InputFieldMergeFailed { message, locations } => Self::InputFieldMergeFailed {
428 message: format!("{message}{appendix}"),
429 locations,
430 },
431 Self::FieldArgumentTypeMismatch { message } => Self::FieldArgumentTypeMismatch {
432 message: format!("{message}{appendix}"),
433 },
434 Self::FieldTypeMismatch { message } => Self::FieldTypeMismatch {
435 message: format!("{message}{appendix}"),
436 },
437 Self::ContextualArgumentNotContextualInAllSubgraphs { message, locations } => {
438 Self::ContextualArgumentNotContextualInAllSubgraphs {
439 message: format!("{message}{appendix}"),
440 locations,
441 }
442 }
443 Self::ArgumentDefaultMismatch { message, locations } => Self::ArgumentDefaultMismatch {
444 message: format!("{message}{appendix}"),
445 locations,
446 },
447 Self::InputFieldDefaultMismatch { message, locations } => {
448 Self::InputFieldDefaultMismatch {
449 message: format!("{message}{appendix}"),
450 locations,
451 }
452 }
453 Self::SubgraphError { .. }
455 | Self::InvalidGraphQLName(..)
456 | Self::FromContextParseError { .. }
457 | Self::UnsupportedSpreadDirective { .. }
458 | Self::ExtensionWithNoBase { .. }
459 | Self::OverrideCollisionWithAnotherDirective { .. }
460 | Self::OverrideFromSelfError { .. }
461 | Self::OverrideLabelInvalid { .. }
462 | Self::OverrideOnInterface { .. }
463 | Self::OverrideSourceHasOverride { .. }
464 | Self::QueryRootMissing { .. } => self,
465 }
466 }
467
468 pub fn locations(&self) -> &[SubgraphLocation] {
469 match self {
470 Self::SubgraphError { locations, .. }
471 | Self::EmptyMergedEnumType { locations, .. }
472 | Self::InputFieldMergeFailed { locations, .. }
473 | Self::ExtensionWithNoBase { locations, .. }
474 | Self::RequiredArgumentMissingInSomeSubgraph { locations, .. }
475 | Self::RequiredInputFieldMissingInSomeSubgraph { locations, .. }
476 | Self::EmptyMergedInputType { locations, .. }
477 | Self::InvalidFieldSharing { locations, .. }
478 | Self::ArgumentDefaultMismatch { locations, .. }
479 | Self::InputFieldDefaultMismatch { locations, .. } => locations,
480 _ => &[],
481 }
482 }
483}
484
485impl SubgraphError {
486 pub fn to_composition_errors(&self) -> impl Iterator<Item = CompositionError> {
487 self.errors
488 .iter()
489 .map(move |error| CompositionError::SubgraphError {
490 subgraph: self.subgraph.clone(),
491 error: error.error.clone(),
492 locations: error
493 .locations
494 .iter()
495 .map(|range| SubgraphLocation {
496 subgraph: self.subgraph.clone(),
497 range: range.clone(),
498 })
499 .collect(),
500 })
501 }
502}
503
504#[derive(Debug, Clone, thiserror::Error)]
516pub enum SingleFederationError {
517 #[error(
518 "An internal error has occurred, please report this bug to Apollo.\n\nDetails: {message}"
519 )]
520 Internal { message: String },
521 #[error("An internal error has occurred, please report this bug to Apollo. Details: {0}")]
522 #[allow(private_interfaces)] InternalRebaseError(#[from] crate::operation::RebaseError),
524 #[error("{message}")]
526 InternalUnmergeableFields { message: String },
527 #[error("{message}")]
531 InvalidGraphQL { message: String },
532 #[error(transparent)]
533 InvalidGraphQLName(#[from] InvalidNameError),
534 #[error("Subgraph invalid: {message}")]
535 InvalidSubgraph { message: String },
536 #[error("Operation name not found")]
537 UnknownOperation,
538 #[error("Must provide operation name if query contains multiple operations")]
539 OperationNameNotProvided,
540 #[error(r#"{message} in @fromContext substring "{context}""#)]
541 FromContextParseError { context: String, message: String },
542 #[error(
543 "Unsupported custom directive @{name} on fragment spread. Due to query transformations during planning, the router requires directives on fragment spreads to support both the FRAGMENT_SPREAD and INLINE_FRAGMENT locations."
544 )]
545 UnsupportedSpreadDirective { name: Name },
546 #[error("{message}")]
547 DirectiveDefinitionInvalid { message: String },
548 #[error("{message}")]
549 TypeDefinitionInvalid { message: String },
550 #[error("{message}")]
551 UnsupportedFederationDirective { message: String },
552 #[error("{message}")]
553 UnsupportedFederationVersion { message: String },
554 #[error("{message}")]
555 UnsupportedLinkedFeature { message: String },
556 #[error("{message}")]
557 UnknownFederationLinkVersion { message: String },
558 #[error("{message}")]
559 UnknownLinkVersion { message: String },
560 #[error(
561 "On type \"{target_type}\", for {application}: field {inner_coordinate} cannot be included because it has arguments (fields with argument are not allowed in @key)"
562 )]
563 KeyFieldsHasArgs {
564 target_type: Name,
565 application: String,
566 inner_coordinate: String,
567 },
568 #[error(
569 "On field \"{coordinate}\", for {application}: field {inner_coordinate} cannot be included because it has arguments (fields with argument are not allowed in @provides)"
570 )]
571 ProvidesFieldsHasArgs {
572 coordinate: String,
573 application: String,
574 inner_coordinate: String,
575 },
576 #[error("On field \"{coordinate}\", for {application}: {message}")]
577 ProvidesFieldsMissingExternal {
578 coordinate: String,
579 application: String,
580 message: String,
581 },
582 #[error("On field \"{coordinate}\", for {application}: {message}")]
583 RequiresFieldsMissingExternal {
584 coordinate: String,
585 application: String,
586 message: String,
587 },
588 #[error("{message}")]
589 KeyUnsupportedOnInterface { message: String },
590 #[error("{message}")]
591 ProvidesUnsupportedOnInterface { message: String },
592 #[error("{message}")]
593 RequiresUnsupportedOnInterface { message: String },
594 #[error(
595 "On type \"{target_type}\", for {application}: cannot have directive applications in the @key(fields:) argument but found {applied_directives}."
596 )]
597 KeyHasDirectiveInFieldsArg {
598 target_type: Name,
599 application: String,
600 applied_directives: String,
601 },
602 #[error(
603 "On field \"{coordinate}\", for {application}: cannot have directive applications in the @provides(fields:) argument but found {applied_directives}."
604 )]
605 ProvidesHasDirectiveInFieldsArg {
606 coordinate: String,
607 application: String,
608 applied_directives: String,
609 },
610 #[error(
611 "On field \"{coordinate}\", for {application}: cannot have directive applications in the @requires(fields:) argument but found {applied_directives}."
612 )]
613 RequiresHasDirectiveInFieldsArg {
614 coordinate: String,
615 application: String,
616 applied_directives: String,
617 },
618 #[error("{message}")]
619 ExternalUnused { message: String },
620 #[error(
621 "Type {type_name} contains only external fields and all those fields are all unused (they do not appear in any @key, @provides or @requires)."
622 )]
623 TypeWithOnlyUnusedExternal { type_name: Name },
624 #[error("{message}")]
625 ProvidesOnNonObjectField { message: String },
626 #[error(
627 "On type \"{target_type}\", for {application}: Invalid value for argument \"fields\": must be a string."
628 )]
629 KeyInvalidFieldsType {
630 target_type: Name,
631 application: String,
632 },
633 #[error(
634 "On field \"{coordinate}\", for {application}: Invalid value for argument \"fields\": must be a string."
635 )]
636 ProvidesInvalidFieldsType {
637 coordinate: String,
638 application: String,
639 },
640 #[error(
641 "On field \"{coordinate}\", for {application}: Invalid value for argument \"fields\": must be a string."
642 )]
643 RequiresInvalidFieldsType {
644 coordinate: String,
645 application: String,
646 },
647 #[error("On type \"{target_type}\", for {application}: {message}")]
648 KeyInvalidFields {
649 target_type: Name,
650 application: String,
651 message: String,
652 },
653 #[error("On field \"{coordinate}\", for {application}: {message}")]
654 ProvidesInvalidFields {
655 coordinate: String,
656 application: String,
657 message: String,
658 },
659 #[error("On field \"{coordinate}\", for {application}: {message}")]
660 RequiresInvalidFields {
661 coordinate: String,
662 application: String,
663 message: String,
664 },
665 #[error("On type \"{target_type}\", for {application}: {message}")]
666 KeyFieldsSelectInvalidType {
667 target_type: Name,
668 application: String,
669 message: String,
670 },
671 #[error(
672 "The schema has a type named \"{expected_name}\" but it is not set as the query root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
673 )]
674 RootQueryUsed {
675 expected_name: Name,
676 found_name: Name,
677 },
678 #[error(
679 "The schema has a type named \"{expected_name}\" but it is not set as the mutation root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
680 )]
681 RootMutationUsed {
682 expected_name: Name,
683 found_name: Name,
684 },
685 #[error(
686 "The schema has a type named \"{expected_name}\" but it is not set as the subscription root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
687 )]
688 RootSubscriptionUsed {
689 expected_name: Name,
690 found_name: Name,
691 },
692 #[error("{message}")]
693 InvalidSubgraphName { message: String },
694 #[error("{message}")]
695 NoQueries { message: String },
696 #[error("{message}")]
697 InterfaceFieldNoImplem { message: String },
698 #[error("{message}")]
699 ExternalTypeMismatch { message: String },
700 #[error("{message}")]
701 ExternalCollisionWithAnotherDirective { message: String },
702 #[error("{message}")]
703 ExternalArgumentMissing { message: String },
704 #[error("{message}")]
705 ExternalArgumentTypeMismatch { message: String },
706 #[error("{message}")]
707 ExternalArgumentDefaultMismatch { message: String },
708 #[error("{message}")]
709 ExternalOnInterface { message: String },
710 #[error("{message}")]
711 MergedDirectiveApplicationOnExternal { message: String },
712 #[error("{message}")]
713 FieldTypeMismatch { message: String },
714 #[error("{message}")]
715 FieldArgumentTypeMismatch { message: String },
716 #[error("{message}")]
717 InputFieldDefaultMismatch { message: String },
718 #[error("{message}")]
719 FieldArgumentDefaultMismatch { message: String },
720 #[error("{message}")]
721 ExtensionWithNoBase { message: String },
722 #[error("{message}")]
723 ExternalMissingOnBase { message: String },
724 #[error("{message}")]
725 InvalidFieldSharing { message: String },
726 #[error("{message}")]
727 InvalidShareableUsage { message: String },
728 #[error("{message}")]
729 InvalidLinkDirectiveUsage { message: String },
730 #[error("{message}")]
731 InvalidLinkIdentifier { message: String },
732 #[error("{message}")]
733 ReferencedInaccessible { message: String },
734 #[error("{message}")]
735 DefaultValueUsesInaccessible { message: String },
736 #[error("{message}")]
737 QueryRootTypeInaccessible { message: String },
738 #[error("{message}")]
739 RequiredInaccessible { message: String },
740 #[error("{message}")]
741 ImplementedByInaccessible { message: String },
742 #[error("{message}")]
743 DisallowedInaccessible { message: String },
744 #[error("{message}")]
745 OnlyInaccessibleChildren { message: String },
746 #[error("{message}")]
747 RequiredInputFieldMissingInSomeSubgraph { message: String },
748 #[error("{message}")]
749 RequiredArgumentMissingInSomeSubgraph { message: String },
750 #[error("{message}")]
751 EmptyMergedInputType { message: String },
752 #[error("{message}")]
753 EnumValueMismatch { message: String },
754 #[error("{message}")]
755 EmptyMergedEnumType { message: String },
756 #[error("{message}")]
757 ShareableHasMismatchedRuntimeTypes { message: String },
758 #[error("{message}")]
759 SatisfiabilityError { message: String },
760 #[error("{message}")]
761 OverrideFromSelfError { message: String },
762 #[error("{message}")]
763 OverrideSourceHasOverride { message: String },
764 #[error("{message}")]
765 OverrideCollisionWithAnotherDirective { message: String },
766 #[error("{message}")]
767 OverrideOnInterface { message: String },
768 #[error("{message}")]
769 UnsupportedFeature {
770 message: String,
771 kind: UnsupportedFeatureKind,
772 },
773 #[error("{message}")]
774 InvalidFederationSupergraph { message: String },
775 #[error("{message}")]
776 DownstreamServiceError { message: String },
777 #[error("{message}")]
778 DirectiveCompositionError { message: String },
779 #[error("{message}")]
780 InterfaceObjectUsageError { message: String },
781 #[error("{message}")]
782 InterfaceKeyNotOnImplementation { message: String },
783 #[error("{message}")]
784 InterfaceKeyMissingImplementationType { message: String },
785 #[error("@defer is not supported on subscriptions")]
786 DeferredSubscriptionUnsupported,
787 #[error("{message}")]
788 QueryPlanComplexityExceeded { message: String },
789 #[error("the caller requested cancellation")]
790 PlanningCancelled,
791 #[error("No plan was found when subgraphs were disabled")]
792 NoPlanFoundWithDisabledSubgraphs,
793 #[error("Context name \"{name}\" may not contain an underscore.")]
794 ContextNameContainsUnderscore { name: String },
795 #[error("Context name \"{name}\" is invalid. It should have only alphanumeric characters.")]
796 ContextNameInvalid { name: String },
797 #[error("{message}")]
798 ContextNotSet { message: String },
799 #[error("{message}")]
800 NoContextReferenced { message: String },
801 #[error("{message}")]
802 NoSelectionForContext { message: String },
803 #[error("{message}")]
804 ContextNoResolvableKey { message: String },
805 #[error("@cost cannot be applied to interface \"{interface}.{field}\"")]
806 CostAppliedToInterfaceField { interface: Name, field: Name },
807 #[error("{message}")]
808 ContextSelectionInvalid { message: String },
809 #[error("{message}")]
810 ListSizeAppliedToNonList { message: String },
811 #[error("{message}")]
812 ListSizeInvalidAssumedSize { message: String },
813 #[error("{message}")]
814 ListSizeInvalidSlicingArgument { message: String },
815 #[error("{message}")]
816 ListSizeInvalidSizedField { message: String },
817 #[error("{message}")]
818 InvalidTagName { message: String },
819 #[error("{message}")]
820 QueryRootMissing { message: String },
821}
822
823impl SingleFederationError {
824 pub fn code(&self) -> ErrorCode {
825 match self {
826 SingleFederationError::Internal { .. } => ErrorCode::Internal,
827 SingleFederationError::InternalRebaseError { .. } => ErrorCode::Internal,
828 SingleFederationError::InternalUnmergeableFields { .. } => ErrorCode::Internal,
829 SingleFederationError::InvalidGraphQL { .. }
830 | SingleFederationError::InvalidGraphQLName(_) => ErrorCode::InvalidGraphQL,
831 SingleFederationError::InvalidSubgraph { .. } => ErrorCode::InvalidGraphQL,
832 SingleFederationError::FromContextParseError { .. } => ErrorCode::InvalidGraphQL,
834 SingleFederationError::UnsupportedSpreadDirective { .. } => ErrorCode::InvalidGraphQL,
837 SingleFederationError::UnknownOperation => ErrorCode::InvalidGraphQL,
840 SingleFederationError::OperationNameNotProvided => ErrorCode::InvalidGraphQL,
841 SingleFederationError::DirectiveDefinitionInvalid { .. } => {
842 ErrorCode::DirectiveDefinitionInvalid
843 }
844 SingleFederationError::TypeDefinitionInvalid { .. } => ErrorCode::TypeDefinitionInvalid,
845 SingleFederationError::UnsupportedFederationDirective { .. } => {
846 ErrorCode::UnsupportedFederationDirective
847 }
848 SingleFederationError::UnsupportedFederationVersion { .. } => {
849 ErrorCode::UnsupportedFederationVersion
850 }
851 SingleFederationError::UnsupportedLinkedFeature { .. } => {
852 ErrorCode::UnsupportedLinkedFeature
853 }
854 SingleFederationError::UnknownFederationLinkVersion { .. } => {
855 ErrorCode::UnknownFederationLinkVersion
856 }
857 SingleFederationError::UnknownLinkVersion { .. } => ErrorCode::UnknownLinkVersion,
858 SingleFederationError::KeyFieldsHasArgs { .. } => ErrorCode::KeyFieldsHasArgs,
859 SingleFederationError::ProvidesFieldsHasArgs { .. } => ErrorCode::ProvidesFieldsHasArgs,
860 SingleFederationError::ProvidesFieldsMissingExternal { .. } => {
861 ErrorCode::ProvidesFieldsMissingExternal
862 }
863 SingleFederationError::RequiresFieldsMissingExternal { .. } => {
864 ErrorCode::RequiresFieldsMissingExternal
865 }
866 SingleFederationError::KeyUnsupportedOnInterface { .. } => {
867 ErrorCode::KeyUnsupportedOnInterface
868 }
869 SingleFederationError::ProvidesUnsupportedOnInterface { .. } => {
870 ErrorCode::ProvidesUnsupportedOnInterface
871 }
872 SingleFederationError::RequiresUnsupportedOnInterface { .. } => {
873 ErrorCode::RequiresUnsupportedOnInterface
874 }
875 SingleFederationError::KeyHasDirectiveInFieldsArg { .. } => {
876 ErrorCode::KeyDirectiveInFieldsArgs
877 }
878 SingleFederationError::ProvidesHasDirectiveInFieldsArg { .. } => {
879 ErrorCode::ProvidesDirectiveInFieldsArgs
880 }
881 SingleFederationError::RequiresHasDirectiveInFieldsArg { .. } => {
882 ErrorCode::RequiresDirectiveInFieldsArgs
883 }
884 SingleFederationError::ExternalUnused { .. } => ErrorCode::ExternalUnused,
885 SingleFederationError::TypeWithOnlyUnusedExternal { .. } => {
886 ErrorCode::TypeWithOnlyUnusedExternal
887 }
888 SingleFederationError::ProvidesOnNonObjectField { .. } => {
889 ErrorCode::ProvidesOnNonObjectField
890 }
891 SingleFederationError::KeyInvalidFieldsType { .. } => ErrorCode::KeyInvalidFieldsType,
892 SingleFederationError::ProvidesInvalidFieldsType { .. } => {
893 ErrorCode::ProvidesInvalidFieldsType
894 }
895 SingleFederationError::RequiresInvalidFieldsType { .. } => {
896 ErrorCode::RequiresInvalidFieldsType
897 }
898 SingleFederationError::KeyInvalidFields { .. } => ErrorCode::KeyInvalidFields,
899 SingleFederationError::ProvidesInvalidFields { .. } => ErrorCode::ProvidesInvalidFields,
900 SingleFederationError::RequiresInvalidFields { .. } => ErrorCode::RequiresInvalidFields,
901 SingleFederationError::KeyFieldsSelectInvalidType { .. } => {
902 ErrorCode::KeyFieldsSelectInvalidType
903 }
904 SingleFederationError::RootQueryUsed { .. } => ErrorCode::RootQueryUsed,
905 SingleFederationError::RootMutationUsed { .. } => ErrorCode::RootMutationUsed,
906 SingleFederationError::RootSubscriptionUsed { .. } => ErrorCode::RootSubscriptionUsed,
907 SingleFederationError::InvalidSubgraphName { .. } => ErrorCode::InvalidSubgraphName,
908 SingleFederationError::NoQueries { .. } => ErrorCode::NoQueries,
909 SingleFederationError::InterfaceFieldNoImplem { .. } => {
910 ErrorCode::InterfaceFieldNoImplem
911 }
912 SingleFederationError::ExternalTypeMismatch { .. } => ErrorCode::ExternalTypeMismatch,
913 SingleFederationError::ExternalCollisionWithAnotherDirective { .. } => {
914 ErrorCode::ExternalCollisionWithAnotherDirective
915 }
916 SingleFederationError::ExternalArgumentMissing { .. } => {
917 ErrorCode::ExternalArgumentMissing
918 }
919 SingleFederationError::ExternalArgumentTypeMismatch { .. } => {
920 ErrorCode::ExternalArgumentTypeMismatch
921 }
922 SingleFederationError::ExternalArgumentDefaultMismatch { .. } => {
923 ErrorCode::ExternalArgumentDefaultMismatch
924 }
925 SingleFederationError::ExternalOnInterface { .. } => ErrorCode::ExternalOnInterface,
926 SingleFederationError::MergedDirectiveApplicationOnExternal { .. } => {
927 ErrorCode::MergedDirectiveApplicationOnExternal
928 }
929 SingleFederationError::FieldTypeMismatch { .. } => ErrorCode::FieldTypeMismatch,
930 SingleFederationError::FieldArgumentTypeMismatch { .. } => {
931 ErrorCode::FieldArgumentTypeMismatch
932 }
933 SingleFederationError::InputFieldDefaultMismatch { .. } => {
934 ErrorCode::InputFieldDefaultMismatch
935 }
936 SingleFederationError::FieldArgumentDefaultMismatch { .. } => {
937 ErrorCode::FieldArgumentDefaultMismatch
938 }
939 SingleFederationError::ExtensionWithNoBase { .. } => ErrorCode::ExtensionWithNoBase,
940 SingleFederationError::ExternalMissingOnBase { .. } => ErrorCode::ExternalMissingOnBase,
941 SingleFederationError::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
942 SingleFederationError::InvalidShareableUsage { .. } => ErrorCode::InvalidShareableUsage,
943 SingleFederationError::InvalidLinkDirectiveUsage { .. } => {
944 ErrorCode::InvalidLinkDirectiveUsage
945 }
946 SingleFederationError::InvalidLinkIdentifier { .. } => ErrorCode::InvalidLinkIdentifier,
947 SingleFederationError::ReferencedInaccessible { .. } => {
948 ErrorCode::ReferencedInaccessible
949 }
950 SingleFederationError::DefaultValueUsesInaccessible { .. } => {
951 ErrorCode::DefaultValueUsesInaccessible
952 }
953 SingleFederationError::QueryRootTypeInaccessible { .. } => {
954 ErrorCode::QueryRootTypeInaccessible
955 }
956 SingleFederationError::RequiredInaccessible { .. } => ErrorCode::RequiredInaccessible,
957 SingleFederationError::ImplementedByInaccessible { .. } => {
958 ErrorCode::ImplementedByInaccessible
959 }
960 SingleFederationError::DisallowedInaccessible { .. } => {
961 ErrorCode::DisallowedInaccessible
962 }
963 SingleFederationError::OnlyInaccessibleChildren { .. } => {
964 ErrorCode::OnlyInaccessibleChildren
965 }
966 SingleFederationError::RequiredInputFieldMissingInSomeSubgraph { .. } => {
967 ErrorCode::RequiredInputFieldMissingInSomeSubgraph
968 }
969 SingleFederationError::RequiredArgumentMissingInSomeSubgraph { .. } => {
970 ErrorCode::RequiredArgumentMissingInSomeSubgraph
971 }
972 SingleFederationError::EmptyMergedInputType { .. } => ErrorCode::EmptyMergedInputType,
973 SingleFederationError::EnumValueMismatch { .. } => ErrorCode::EnumValueMismatch,
974 SingleFederationError::EmptyMergedEnumType { .. } => ErrorCode::EmptyMergedEnumType,
975 SingleFederationError::ShareableHasMismatchedRuntimeTypes { .. } => {
976 ErrorCode::ShareableHasMismatchedRuntimeTypes
977 }
978 SingleFederationError::SatisfiabilityError { .. } => ErrorCode::SatisfiabilityError,
979 SingleFederationError::OverrideFromSelfError { .. } => ErrorCode::OverrideFromSelfError,
980 SingleFederationError::OverrideSourceHasOverride { .. } => {
981 ErrorCode::OverrideSourceHasOverride
982 }
983 SingleFederationError::OverrideCollisionWithAnotherDirective { .. } => {
984 ErrorCode::OverrideCollisionWithAnotherDirective
985 }
986 SingleFederationError::OverrideOnInterface { .. } => ErrorCode::OverrideOnInterface,
987 SingleFederationError::UnsupportedFeature { .. } => ErrorCode::UnsupportedFeature,
988 SingleFederationError::InvalidFederationSupergraph { .. } => {
989 ErrorCode::InvalidFederationSupergraph
990 }
991 SingleFederationError::DownstreamServiceError { .. } => {
992 ErrorCode::DownstreamServiceError
993 }
994 SingleFederationError::DirectiveCompositionError { .. } => {
995 ErrorCode::DirectiveCompositionError
996 }
997 SingleFederationError::InterfaceObjectUsageError { .. } => {
998 ErrorCode::InterfaceObjectUsageError
999 }
1000 SingleFederationError::InterfaceKeyNotOnImplementation { .. } => {
1001 ErrorCode::InterfaceKeyNotOnImplementation
1002 }
1003 SingleFederationError::InterfaceKeyMissingImplementationType { .. } => {
1004 ErrorCode::InterfaceKeyMissingImplementationType
1005 }
1006 SingleFederationError::DeferredSubscriptionUnsupported => ErrorCode::Internal,
1007 SingleFederationError::QueryPlanComplexityExceeded { .. } => {
1008 ErrorCode::QueryPlanComplexityExceededError
1009 }
1010 SingleFederationError::PlanningCancelled => ErrorCode::Internal,
1011 SingleFederationError::NoPlanFoundWithDisabledSubgraphs => {
1012 ErrorCode::NoPlanFoundWithDisabledSubgraphs
1013 }
1014 SingleFederationError::ContextNameContainsUnderscore { .. } => {
1015 ErrorCode::ContextNameContainsUnderscore
1016 }
1017 SingleFederationError::ContextNameInvalid { .. } => ErrorCode::ContextNameInvalid,
1018 SingleFederationError::ContextNotSet { .. } => ErrorCode::ContextNotSet,
1019 SingleFederationError::NoContextReferenced { .. } => ErrorCode::NoContextReferenced,
1020 SingleFederationError::NoSelectionForContext { .. } => ErrorCode::NoSelectionForContext,
1021 SingleFederationError::ContextNoResolvableKey { .. } => {
1022 ErrorCode::ContextNoResolvableKey
1023 }
1024 SingleFederationError::ContextSelectionInvalid { .. } => {
1025 ErrorCode::ContextSelectionInvalid
1026 }
1027 SingleFederationError::CostAppliedToInterfaceField { .. } => {
1028 ErrorCode::CostAppliedToInterfaceField
1029 }
1030 SingleFederationError::ListSizeAppliedToNonList { .. } => {
1031 ErrorCode::ListSizeAppliedToNonList
1032 }
1033 SingleFederationError::ListSizeInvalidAssumedSize { .. } => {
1034 ErrorCode::ListSizeInvalidAssumedSize
1035 }
1036 SingleFederationError::ListSizeInvalidSlicingArgument { .. } => {
1037 ErrorCode::ListSizeInvalidSlicingArgument
1038 }
1039 SingleFederationError::ListSizeInvalidSizedField { .. } => {
1040 ErrorCode::ListSizeInvalidSizedField
1041 }
1042 #[allow(unused)]
1043 SingleFederationError::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
1044 SingleFederationError::InvalidTagName { .. } => ErrorCode::InvalidTagName,
1045 SingleFederationError::QueryRootMissing { .. } => ErrorCode::QueryRootMissing,
1046 }
1047 }
1048
1049 pub fn code_string(&self) -> String {
1050 self.code().definition().code().to_string()
1051 }
1052
1053 pub(crate) fn root_already_used(
1054 operation_type: OperationType,
1055 expected_name: Name,
1056 found_name: Name,
1057 ) -> Self {
1058 match operation_type {
1059 OperationType::Query => Self::RootQueryUsed {
1060 expected_name,
1061 found_name,
1062 },
1063 OperationType::Mutation => Self::RootMutationUsed {
1064 expected_name,
1065 found_name,
1066 },
1067 OperationType::Subscription => Self::RootSubscriptionUsed {
1068 expected_name,
1069 found_name,
1070 },
1071 }
1072 }
1073}
1074
1075impl From<InvalidNameError> for FederationError {
1076 fn from(err: InvalidNameError) -> Self {
1077 SingleFederationError::from(err).into()
1078 }
1079}
1080
1081impl From<FederationSpecError> for FederationError {
1082 fn from(err: FederationSpecError) -> Self {
1083 let message = err.to_string();
1086 match err {
1087 FederationSpecError::UnsupportedVersionError { .. } => {
1088 SingleFederationError::UnsupportedFederationVersion { message }.into()
1089 }
1090 FederationSpecError::UnsupportedFederationDirective { .. } => {
1091 SingleFederationError::UnsupportedFederationDirective { message }.into()
1092 }
1093 FederationSpecError::InvalidGraphQLName(message) => message.into(),
1094 }
1095 }
1096}
1097
1098#[derive(Debug, Clone, thiserror::Error, Default)]
1099pub struct MultipleFederationErrors {
1100 pub(crate) errors: Vec<SingleFederationError>,
1101}
1102
1103impl MultipleFederationErrors {
1104 pub fn new() -> Self {
1105 Self { errors: vec![] }
1106 }
1107
1108 pub fn push(&mut self, error: FederationError) {
1109 match error {
1110 FederationError::SingleFederationError(error) => {
1111 self.errors.push(error);
1112 }
1113 FederationError::MultipleFederationErrors(errors) => {
1114 self.errors.extend(errors.errors);
1115 }
1116 FederationError::AggregateFederationError(errors) => {
1117 self.errors.extend(errors.causes);
1118 }
1119 }
1120 }
1121
1122 pub(crate) fn and_try(mut self, other: Result<(), FederationError>) -> Self {
1123 match other {
1124 Ok(_) => self,
1125 Err(e) => {
1126 self.push(e);
1127 self
1128 }
1129 }
1130 }
1131}
1132
1133impl Display for MultipleFederationErrors {
1134 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1135 write!(f, "The following errors occurred:")?;
1136 for error in &self.errors {
1137 write!(f, "\n - ")?;
1138 for c in error.to_string().chars() {
1139 if c == '\n' {
1140 write!(f, "\n ")?;
1141 } else {
1142 f.write_char(c)?;
1143 }
1144 }
1145 }
1146 Ok(())
1147 }
1148}
1149
1150impl FromIterator<SingleFederationError> for MultipleFederationErrors {
1151 fn from_iter<T: IntoIterator<Item = SingleFederationError>>(iter: T) -> Self {
1152 Self {
1153 errors: iter.into_iter().collect(),
1154 }
1155 }
1156}
1157
1158#[derive(Debug, Clone, thiserror::Error)]
1159pub struct AggregateFederationError {
1160 pub code: String,
1161 pub message: String,
1162 pub causes: Vec<SingleFederationError>,
1163}
1164
1165impl Display for AggregateFederationError {
1166 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1167 write!(f, "[{}] {}\nCaused by:", self.code, self.message)?;
1168 for error in &self.causes {
1169 write!(f, "\n\n - ")?;
1170 for c in error.to_string().chars() {
1171 if c == '\n' {
1172 write!(f, "\n ")?;
1173 } else {
1174 f.write_char(c)?;
1175 }
1176 }
1177 }
1178 Ok(())
1179 }
1180}
1181
1182#[derive(Clone, thiserror::Error)]
1187pub enum FederationError {
1188 #[error(transparent)]
1189 SingleFederationError(#[from] SingleFederationError),
1190 #[error(transparent)]
1191 MultipleFederationErrors(#[from] MultipleFederationErrors),
1192 #[error(transparent)]
1193 AggregateFederationError(#[from] AggregateFederationError),
1194}
1195
1196impl std::fmt::Debug for FederationError {
1197 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1198 match self {
1199 Self::SingleFederationError(inner) => std::fmt::Debug::fmt(inner, f),
1200 Self::MultipleFederationErrors(inner) => std::fmt::Debug::fmt(inner, f),
1201 Self::AggregateFederationError(inner) => std::fmt::Debug::fmt(inner, f),
1202 }
1203 }
1204}
1205
1206impl From<DiagnosticList> for FederationError {
1207 fn from(value: DiagnosticList) -> Self {
1208 let errors: Vec<_> = value
1209 .iter()
1210 .map(|d| SingleFederationError::InvalidGraphQL {
1211 message: d.to_string(),
1212 })
1213 .collect();
1214 match errors.len().cmp(&1) {
1215 Ordering::Less => internal_error!("diagnostic list is unexpectedly empty"),
1216 Ordering::Equal => errors[0].clone().into(),
1217 Ordering::Greater => MultipleFederationErrors { errors }.into(),
1218 }
1219 }
1220}
1221
1222impl<T> From<WithErrors<T>> for FederationError {
1223 fn from(value: WithErrors<T>) -> Self {
1224 value.errors.into()
1225 }
1226}
1227
1228impl From<std::convert::Infallible> for FederationError {
1231 fn from(_: std::convert::Infallible) -> Self {
1232 unreachable!("Infallible should never be converted to FederationError")
1233 }
1234}
1235
1236impl FederationError {
1237 pub fn internal(message: impl Into<String>) -> Self {
1238 SingleFederationError::Internal {
1239 message: message.into(),
1240 }
1241 .into()
1242 }
1243
1244 pub fn merge(self, other: Self) -> Self {
1245 let mut result = MultipleFederationErrors::new();
1246 result.push(self);
1247 result.push(other);
1248 result.into()
1249 }
1250
1251 pub fn into_errors(self) -> Vec<SingleFederationError> {
1252 match self {
1253 FederationError::SingleFederationError(e) => vec![e],
1254 FederationError::MultipleFederationErrors(e) => e.errors,
1255 FederationError::AggregateFederationError(e) => e.causes,
1256 }
1257 }
1258
1259 pub fn errors(&self) -> Vec<&SingleFederationError> {
1260 match self {
1261 FederationError::SingleFederationError(e) => vec![e],
1262 FederationError::MultipleFederationErrors(e) => e.errors.iter().collect(),
1263 FederationError::AggregateFederationError(e) => e.causes.iter().collect(),
1264 }
1265 }
1266
1267 pub fn has_invalid_graphql_error(&self) -> bool {
1268 self.errors()
1269 .into_iter()
1270 .any(|e| matches!(e, SingleFederationError::InvalidGraphQL { .. }))
1271 }
1272}
1273
1274pub trait MultiTry<U> {
1276 type Output;
1277
1278 fn and_try(self, other: Result<U, FederationError>) -> Self::Output;
1279}
1280
1281impl<U> MultiTry<U> for Result<(), FederationError> {
1282 type Output = Result<U, FederationError>;
1283
1284 fn and_try(self, other: Result<U, FederationError>) -> Result<U, FederationError> {
1285 match (self, other) {
1286 (Ok(_a), Ok(b)) => Ok(b),
1287 (Ok(_a), Err(b)) => Err(b),
1288 (Err(a), Ok(_b)) => Err(a),
1289 (Err(a), Err(b)) => Err(a.merge(b)),
1290 }
1291 }
1292}
1293
1294pub trait MultiTryAll: Sized + Iterator {
1295 fn try_for_all<F>(self, mut predicate: F) -> Result<(), FederationError>
1300 where
1301 F: FnMut(Self::Item) -> Result<(), FederationError>,
1302 {
1303 let mut errors = MultipleFederationErrors::new();
1304 for item in self {
1305 match predicate(item) {
1306 Ok(()) => {}
1307 Err(e) => errors.push(e),
1308 }
1309 }
1310 errors.into_result()
1311 }
1312}
1313
1314impl<I: Iterator> MultiTryAll for I {}
1315
1316impl MultipleFederationErrors {
1317 pub fn into_result(self) -> Result<(), FederationError> {
1321 match self.errors.len().cmp(&1) {
1322 Ordering::Less => Ok(()),
1323 Ordering::Equal => Err(self.errors[0].clone().into()),
1324 Ordering::Greater => Err(self.into()),
1325 }
1326 }
1327}
1328
1329const FED1_CODE: &str = "0.x";
1332
1333#[derive(Debug, Clone)]
1334pub struct ErrorCodeMetadata {
1335 pub added_in: &'static str,
1336 pub replaces: &'static [&'static str],
1337}
1338
1339#[derive(Debug)]
1340pub struct ErrorCodeDefinition {
1341 code: String,
1342 doc_description: String,
1345 metadata: ErrorCodeMetadata,
1346}
1347
1348impl ErrorCodeDefinition {
1349 fn new(code: String, doc_description: String, metadata: Option<ErrorCodeMetadata>) -> Self {
1350 Self {
1351 code,
1352 doc_description,
1353 metadata: metadata.unwrap_or_else(|| DEFAULT_METADATA.clone()),
1354 }
1355 }
1356
1357 pub fn code(&self) -> &str {
1358 &self.code
1359 }
1360
1361 pub fn doc_description(&self) -> &str {
1362 &self.doc_description
1363 }
1364
1365 pub fn metadata(&self) -> &ErrorCodeMetadata {
1366 &self.metadata
1367 }
1368}
1369
1370static DEFAULT_METADATA: ErrorCodeMetadata = ErrorCodeMetadata {
1375 added_in: "2.0.0",
1376 replaces: &[],
1377};
1378
1379struct ErrorCodeCategory<TElement: Clone + Into<String>> {
1380 extract_code: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1382 make_doc_description: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1384 metadata: ErrorCodeMetadata,
1385}
1386
1387impl<TElement: Clone + Into<String>> ErrorCodeCategory<TElement> {
1388 fn new(
1389 extract_code: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1390 make_doc_description: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1391 metadata: Option<ErrorCodeMetadata>,
1392 ) -> Self {
1393 Self {
1394 extract_code,
1395 make_doc_description,
1396 metadata: metadata.unwrap_or_else(|| DEFAULT_METADATA.clone()),
1397 }
1398 }
1399
1400 fn create_code(&self, element: TElement) -> ErrorCodeDefinition {
1403 ErrorCodeDefinition::new(
1404 (self.extract_code)(element.clone()),
1405 (self.make_doc_description)(element),
1406 Some(self.metadata.clone()),
1407 )
1408 }
1409}
1410
1411impl ErrorCodeCategory<String> {
1412 fn new_federation_directive(
1413 code_suffix: String,
1414 make_doc_description: Box<dyn 'static + Send + Sync + Fn(String) -> String>,
1415 metadata: Option<ErrorCodeMetadata>,
1416 ) -> Self {
1417 Self::new(
1418 Box::new(move |element: String| format!("{}_{}", element.to_uppercase(), code_suffix)),
1419 make_doc_description,
1420 metadata,
1421 )
1422 }
1423}
1424
1425static INVALID_GRAPHQL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1426 ErrorCodeDefinition::new(
1427 "INVALID_GRAPHQL".to_owned(),
1428 "A schema is invalid GraphQL: it violates one of the rule of the specification.".to_owned(),
1429 None,
1430 )
1431});
1432static DIRECTIVE_DEFINITION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1433 ErrorCodeDefinition::new(
1434 "DIRECTIVE_DEFINITION_INVALID".to_owned(),
1435 "A built-in or federation directive has an invalid definition in the schema.".to_owned(),
1436 Some(ErrorCodeMetadata {
1437 replaces: &["TAG_DEFINITION_INVALID"],
1438 ..DEFAULT_METADATA.clone()
1439 }),
1440 )
1441});
1442
1443static TYPE_DEFINITION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1444 ErrorCodeDefinition::new(
1445 "TYPE_DEFINITION_INVALID".to_owned(),
1446 "A built-in or federation type has an invalid definition in the schema.".to_owned(),
1447 None,
1448 )
1449});
1450
1451static UNSUPPORTED_LINKED_FEATURE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1452 ErrorCodeDefinition::new(
1453 "UNSUPPORTED_LINKED_FEATURE".to_owned(),
1454 "Indicates that a feature used in a @link is either unsupported or is used with unsupported options.".to_owned(),
1455 None,
1456 )
1457});
1458
1459static UNKNOWN_FEDERATION_LINK_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1460 ErrorCodeDefinition::new(
1461 "UNKNOWN_FEDERATION_LINK_VERSION".to_owned(),
1462 "The version of federation in a @link directive on the schema is unknown.".to_owned(),
1463 None,
1464 )
1465});
1466
1467static UNKNOWN_LINK_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1468 ErrorCodeDefinition::new(
1469 "UNKNOWN_LINK_VERSION".to_owned(),
1470 "The version of @link set on the schema is unknown.".to_owned(),
1471 Some(ErrorCodeMetadata {
1472 added_in: "2.1.0",
1473 replaces: &[],
1474 }),
1475 )
1476});
1477
1478static FIELDS_HAS_ARGS: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1479 ErrorCodeCategory::new_federation_directive(
1480 "FIELDS_HAS_ARGS".to_owned(),
1481 Box::new(|directive| {
1482 format!(
1483 "The `fields` argument of a `@{directive}` directive includes a field defined with arguments (which is not currently supported)."
1484 )
1485 }),
1486 None,
1487 )
1488});
1489
1490static KEY_FIELDS_HAS_ARGS: LazyLock<ErrorCodeDefinition> =
1491 LazyLock::new(|| FIELDS_HAS_ARGS.create_code("key".to_owned()));
1492
1493static PROVIDES_FIELDS_HAS_ARGS: LazyLock<ErrorCodeDefinition> =
1494 LazyLock::new(|| FIELDS_HAS_ARGS.create_code("provides".to_owned()));
1495
1496static DIRECTIVE_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(
1497 || {
1498 ErrorCodeCategory::new_federation_directive(
1499 "FIELDS_MISSING_EXTERNAL".to_owned(),
1500 Box::new(|directive| {
1501 format!(
1502 "The `fields` argument of a `@{directive}` directive includes a field that is not marked as `@external`."
1503 )
1504 }),
1505 Some(ErrorCodeMetadata {
1506 added_in: FED1_CODE,
1507 replaces: &[],
1508 }),
1509 )
1510 },
1511);
1512
1513static PROVIDES_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeDefinition> =
1514 LazyLock::new(|| DIRECTIVE_FIELDS_MISSING_EXTERNAL.create_code("provides".to_owned()));
1515static REQUIRES_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeDefinition> =
1516 LazyLock::new(|| DIRECTIVE_FIELDS_MISSING_EXTERNAL.create_code("requires".to_owned()));
1517
1518static DIRECTIVE_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeCategory<String>> =
1519 LazyLock::new(|| {
1520 ErrorCodeCategory::new_federation_directive(
1521 "UNSUPPORTED_ON_INTERFACE".to_owned(),
1522 Box::new(|directive| {
1523 let suffix = if directive == "key" {
1524 "only supported when @linking to federation 2.3+"
1525 } else {
1526 "not (yet) supported"
1527 };
1528 format!("A `@{directive}` directive is used on an interface, which is {suffix}.")
1529 }),
1530 None,
1531 )
1532 });
1533
1534static KEY_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1535 LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("key".to_owned()));
1536static PROVIDES_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1537 LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("provides".to_owned()));
1538static REQUIRES_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1539 LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("requires".to_owned()));
1540
1541static DIRECTIVE_IN_FIELDS_ARG: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1542 ErrorCodeCategory::new_federation_directive(
1543 "DIRECTIVE_IN_FIELDS_ARG".to_owned(),
1544 Box::new(|directive| {
1545 format!(
1546 "The `fields` argument of a `@{directive}` directive includes some directive applications. This is not supported"
1547 )
1548 }),
1549 Some(ErrorCodeMetadata {
1550 added_in: "2.1.0",
1551 replaces: &[],
1552 }),
1553 )
1554});
1555
1556static KEY_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1557 LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("key".to_owned()));
1558static PROVIDES_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1559 LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("provides".to_owned()));
1560static REQUIRES_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1561 LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("requires".to_owned()));
1562
1563static EXTERNAL_UNUSED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1564 ErrorCodeDefinition::new(
1565 "EXTERNAL_UNUSED".to_owned(),
1566 "An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implementation.".to_owned(),
1567 Some(ErrorCodeMetadata {
1568 added_in: FED1_CODE,
1569 replaces: &[],
1570 }),
1571)
1572});
1573
1574static TYPE_WITH_ONLY_UNUSED_EXTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1575 ErrorCodeDefinition::new(
1576 "TYPE_WITH_ONLY_UNUSED_EXTERNAL".to_owned(),
1577 [
1578 "A federation 1 schema has a composite type comprised only of unused external fields.".to_owned(),
1579 format!("Note that this error can _only_ be raised for federation 1 schema as federation 2 schema do not allow unused external fields (and errors with code {} will be raised in that case).", EXTERNAL_UNUSED.code),
1580 "But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automatically removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised".to_owned()
1581 ].join(" "),
1582 None,
1583)
1584});
1585
1586static PROVIDES_ON_NON_OBJECT_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1587 ErrorCodeDefinition::new(
1588 "PROVIDES_ON_NON_OBJECT_FIELD".to_owned(),
1589 "A `@provides` directive is used to mark a field whose base type is not an object type."
1590 .to_owned(),
1591 None,
1592 )
1593});
1594
1595static DIRECTIVE_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1596 ErrorCodeCategory::new_federation_directive(
1597 "INVALID_FIELDS_TYPE".to_owned(),
1598 Box::new(|directive| {
1599 format!(
1600 "The value passed to the `fields` argument of a `@{directive}` directive is not a string."
1601 )
1602 }),
1603 None,
1604 )
1605});
1606
1607static KEY_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1608 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("key".to_owned()));
1609static PROVIDES_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1610 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("provides".to_owned()));
1611static REQUIRES_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1612 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("requires".to_owned()));
1613
1614static DIRECTIVE_INVALID_FIELDS: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1615 ErrorCodeCategory::new_federation_directive(
1616 "INVALID_FIELDS".to_owned(),
1617 Box::new(|directive| {
1618 format!(
1619 "The `fields` argument of a `@{directive}` directive is invalid (it has invalid syntax, includes unknown fields, ...)."
1620 )
1621 }),
1622 None,
1623 )
1624});
1625
1626static KEY_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1627 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("key".to_owned()));
1628static PROVIDES_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1629 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("provides".to_owned()));
1630static REQUIRES_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1631 LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("requires".to_owned()));
1632
1633static KEY_FIELDS_SELECT_INVALID_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1634 ErrorCodeDefinition::new(
1635 "KEY_FIELDS_SELECT_INVALID_TYPE".to_owned(),
1636 "The `fields` argument of `@key` directive includes a field whose type is a list, interface, or union type. Fields of these types cannot be part of a `@key`".to_owned(),
1637 Some(ErrorCodeMetadata {
1638 added_in: FED1_CODE,
1639 replaces: &[],
1640 }),
1641)
1642});
1643
1644static ROOT_TYPE_USED: LazyLock<ErrorCodeCategory<SchemaRootKind>> = LazyLock::new(|| {
1645 ErrorCodeCategory::new(
1646 Box::new(|element| {
1647 let kind: String = element.into();
1648 format!("ROOT_{}_USED", kind.to_uppercase())
1649 }),
1650 Box::new(|element| {
1651 let kind: String = element.into();
1652 format!(
1653 "A subgraph's schema defines a type with the name `{kind}`, while also specifying a _different_ type name as the root query object. This is not allowed."
1654 )
1655 }),
1656 Some(ErrorCodeMetadata {
1657 added_in: FED1_CODE,
1658 replaces: &[],
1659 }),
1660 )
1661});
1662
1663static ROOT_QUERY_USED: LazyLock<ErrorCodeDefinition> =
1664 LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Query));
1665static ROOT_MUTATION_USED: LazyLock<ErrorCodeDefinition> =
1666 LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Mutation));
1667static ROOT_SUBSCRIPTION_USED: LazyLock<ErrorCodeDefinition> =
1668 LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Subscription));
1669
1670static INVALID_SUBGRAPH_NAME: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1671 ErrorCodeDefinition::new(
1672 "INVALID_SUBGRAPH_NAME".to_owned(),
1673 "A subgraph name is invalid (subgraph names cannot be a single underscore (\"_\"))."
1674 .to_owned(),
1675 None,
1676 )
1677});
1678
1679static NO_QUERIES: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1680 ErrorCodeDefinition::new(
1681 "NO_QUERIES".to_owned(),
1682 "None of the composed subgraphs expose any query.".to_owned(),
1683 None,
1684 )
1685});
1686
1687static INTERFACE_FIELD_NO_IMPLEM: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1688 ErrorCodeDefinition::new(
1689 "INTERFACE_FIELD_NO_IMPLEM".to_owned(),
1690 "After subgraph merging, an implementation is missing a field of one of the interface it implements (which can happen for valid subgraphs).".to_owned(),
1691 None,
1692 )
1693});
1694
1695static TYPE_KIND_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1696 ErrorCodeDefinition::new(
1697 "TYPE_KIND_MISMATCH".to_owned(),
1698 "A type has the same name in different subgraphs, but a different kind. For instance, one definition is an object type but another is an interface.".to_owned(),
1699 Some(ErrorCodeMetadata {
1700 replaces: &["VALUE_TYPE_KIND_MISMATCH", "EXTENSION_OF_WRONG_KIND", "ENUM_MISMATCH_TYPE"],
1701 ..DEFAULT_METADATA.clone()
1702 }),
1703 )
1704});
1705
1706static EXTERNAL_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1707 ErrorCodeDefinition::new(
1708 "EXTERNAL_TYPE_MISMATCH".to_owned(),
1709 "An `@external` field has a type that is incompatible with the declaration(s) of that field in other subgraphs.".to_owned(),
1710 Some(ErrorCodeMetadata {
1711 added_in: FED1_CODE,
1712 replaces: &[],
1713 }),
1714 )
1715});
1716
1717static EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE: LazyLock<ErrorCodeDefinition> =
1718 LazyLock::new(|| {
1719 ErrorCodeDefinition::new(
1720 "EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE".to_owned(),
1721 "The @external directive collides with other directives in some situations.".to_owned(),
1722 Some(ErrorCodeMetadata {
1723 added_in: "2.1.0",
1724 replaces: &[],
1725 }),
1726 )
1727 });
1728
1729static EXTERNAL_ARGUMENT_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1730 ErrorCodeDefinition::new(
1731 "EXTERNAL_ARGUMENT_MISSING".to_owned(),
1732 "An `@external` field is missing some arguments present in the declaration(s) of that field in other subgraphs.".to_owned(),
1733 None,
1734 )
1735});
1736
1737static EXTERNAL_ARGUMENT_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1738 ErrorCodeDefinition::new(
1739 "EXTERNAL_ARGUMENT_TYPE_MISMATCH".to_owned(),
1740 "An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.".to_owned(),
1741 None,
1742 )
1743});
1744
1745static EXTERNAL_ARGUMENT_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1746 ErrorCodeDefinition::new(
1747 "EXTERNAL_ARGUMENT_DEFAULT_MISMATCH".to_owned(),
1748 "An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.".to_owned(),
1749 None,
1750 )
1751});
1752
1753static EXTERNAL_ON_INTERFACE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1754 ErrorCodeDefinition::new(
1755 "EXTERNAL_ON_INTERFACE".to_owned(),
1756 "The field of an interface type is marked with `@external`: as external is about marking field not resolved by the subgraph and as interface field are not resolved (only implementations of those fields are), an \"external\" interface field is nonsensical".to_owned(),
1757 None,
1758 )
1759});
1760
1761static MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(
1762 || {
1763 ErrorCodeDefinition::new(
1764 "MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL".to_owned(),
1765 "In a subgraph, a field is both marked @external and has a merged directive applied to it".to_owned(),
1766 None,
1767 )
1768 },
1769);
1770
1771static FIELD_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1772 ErrorCodeDefinition::new(
1773 "FIELD_TYPE_MISMATCH".to_owned(),
1774 "A field has a type that is incompatible with other declarations of that field in other subgraphs.".to_owned(),
1775 Some(ErrorCodeMetadata {
1776 replaces: &["VALUE_TYPE_FIELD_TYPE_MISMATCH"],
1777 ..DEFAULT_METADATA.clone()
1778 }),
1779 )
1780});
1781
1782static FIELD_ARGUMENT_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1783 ErrorCodeDefinition::new(
1784 "FIELD_ARGUMENT_TYPE_MISMATCH".to_owned(),
1785 "An argument (of a field/directive) has a type that is incompatible with that of other declarations of that same argument in other subgraphs.".to_owned(),
1786 Some(ErrorCodeMetadata {
1787 replaces: &["VALUE_TYPE_INPUT_VALUE_MISMATCH"],
1788 ..DEFAULT_METADATA.clone()
1789 }),
1790 )
1791});
1792
1793static INPUT_FIELD_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1794 ErrorCodeDefinition::new(
1795 "INPUT_FIELD_DEFAULT_MISMATCH".to_owned(),
1796 "An input field has a default value that is incompatible with other declarations of that field in other subgraphs.".to_owned(),
1797 None,
1798 )
1799});
1800
1801static FIELD_ARGUMENT_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1802 ErrorCodeDefinition::new(
1803 "FIELD_ARGUMENT_DEFAULT_MISMATCH".to_owned(),
1804 "An argument (of a field/directive) has a default value that is incompatible with that of other declarations of that same argument in other subgraphs.".to_owned(),
1805 None,
1806 )
1807});
1808
1809static EXTENSION_WITH_NO_BASE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1810 ErrorCodeDefinition::new(
1811 "EXTENSION_WITH_NO_BASE".to_owned(),
1812 "A subgraph is attempting to `extend` a type that is not originally defined in any known subgraph.".to_owned(),
1813 Some(ErrorCodeMetadata {
1814 added_in: FED1_CODE,
1815 replaces: &[],
1816 }),
1817 )
1818});
1819
1820static EXTERNAL_MISSING_ON_BASE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1821 ErrorCodeDefinition::new(
1822 "EXTERNAL_MISSING_ON_BASE".to_owned(),
1823 "A field is marked as `@external` in a subgraph but with no non-external declaration in any other subgraph.".to_owned(),
1824 Some(ErrorCodeMetadata {
1825 added_in: FED1_CODE,
1826 replaces: &[],
1827 }),
1828 )
1829});
1830
1831static INVALID_FIELD_SHARING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1832 ErrorCodeDefinition::new(
1833 "INVALID_FIELD_SHARING".to_owned(),
1834 "A field that is non-shareable in at least one subgraph is resolved by multiple subgraphs."
1835 .to_owned(),
1836 None,
1837 )
1838});
1839
1840static INVALID_SHAREABLE_USAGE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1841 ErrorCodeDefinition::new(
1842 "INVALID_SHAREABLE_USAGE".to_owned(),
1843 "The `@shareable` federation directive is used in an invalid way.".to_owned(),
1844 Some(ErrorCodeMetadata {
1845 added_in: "2.1.2",
1846 replaces: &[],
1847 }),
1848 )
1849});
1850
1851static INVALID_LINK_DIRECTIVE_USAGE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1852 ErrorCodeDefinition::new(
1853 "INVALID_LINK_DIRECTIVE_USAGE".to_owned(),
1854 "An application of the @link directive is invalid/does not respect the specification."
1855 .to_owned(),
1856 None,
1857 )
1858});
1859
1860static INVALID_LINK_IDENTIFIER: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1861 ErrorCodeDefinition::new(
1862 "INVALID_LINK_IDENTIFIER".to_owned(),
1863 "A url/version for a @link feature is invalid/does not respect the specification."
1864 .to_owned(),
1865 Some(ErrorCodeMetadata {
1866 added_in: "2.1.0",
1867 replaces: &[],
1868 }),
1869 )
1870});
1871
1872static LINK_IMPORT_NAME_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1873 ErrorCodeDefinition::new(
1874 "LINK_IMPORT_NAME_MISMATCH".to_owned(),
1875 "The import name for a merged directive (as declared by the relevant `@link(import:)` argument) is inconsistent between subgraphs.".to_owned(),
1876 None,
1877 )
1878});
1879
1880static REFERENCED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1881 ErrorCodeDefinition::new(
1882 "REFERENCED_INACCESSIBLE".to_owned(),
1883 "An element is marked as @inaccessible but is referenced by an element visible in the API schema.".to_owned(),
1884 None,
1885 )
1886});
1887
1888static DEFAULT_VALUE_USES_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1889 ErrorCodeDefinition::new(
1890 "DEFAULT_VALUE_USES_INACCESSIBLE".to_owned(),
1891 "An element is marked as @inaccessible but is used in the default value of an element visible in the API schema.".to_owned(),
1892 None,
1893 )
1894});
1895
1896static QUERY_ROOT_TYPE_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1897 ErrorCodeDefinition::new(
1898 "QUERY_ROOT_TYPE_INACCESSIBLE".to_owned(),
1899 "An element is marked as @inaccessible but is the query root type, which must be visible in the API schema.".to_owned(),
1900 None,
1901 )
1902});
1903
1904static REQUIRED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1905 ErrorCodeDefinition::new(
1906 "REQUIRED_INACCESSIBLE".to_owned(),
1907 "An element is marked as @inaccessible but is required by an element visible in the API schema.".to_owned(),
1908 None,
1909 )
1910});
1911
1912static IMPLEMENTED_BY_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1913 ErrorCodeDefinition::new(
1914 "IMPLEMENTED_BY_INACCESSIBLE".to_owned(),
1915 "An element is marked as @inaccessible but implements an element visible in the API schema.".to_owned(),
1916 None,
1917 )
1918});
1919
1920static DISALLOWED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1921 ErrorCodeDefinition::new(
1922 "DISALLOWED_INACCESSIBLE".to_owned(),
1923 "An element is marked as @inaccessible that is not allowed to be @inaccessible.".to_owned(),
1924 None,
1925 )
1926});
1927
1928static ONLY_INACCESSIBLE_CHILDREN: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1929 ErrorCodeDefinition::new(
1930 "ONLY_INACCESSIBLE_CHILDREN".to_owned(),
1931 "A type visible in the API schema has only @inaccessible children.".to_owned(),
1932 None,
1933 )
1934});
1935
1936static REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(
1937 || {
1938 ErrorCodeDefinition::new(
1939 "REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH".to_owned(),
1940 "A field of an input object type is mandatory in some subgraphs, but the field is not defined in all the subgraphs that define the input object type.".to_owned(),
1941 None,
1942 )
1943 },
1944);
1945
1946static REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(
1947 || {
1948 ErrorCodeDefinition::new(
1949 "REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH".to_owned(),
1950 "An argument of a field or directive definition is mandatory in some subgraphs, but the argument is not defined in all the subgraphs that define the field or directive definition.".to_owned(),
1951 None,
1952 )
1953 },
1954);
1955
1956static EMPTY_MERGED_INPUT_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1957 ErrorCodeDefinition::new(
1958 "EMPTY_MERGED_INPUT_TYPE".to_owned(),
1959 "An input object type has no field common to all the subgraphs that define the type. Merging that type would result in an invalid empty input object type.".to_owned(),
1960 None,
1961 )
1962});
1963
1964static INPUT_FIELD_MERGE_FAILED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1965 ErrorCodeDefinition::new(
1966 "INPUT_FIELD_MERGE_FAILED".to_owned(),
1967 "Failed to merge an input object field due to incompatible definitions across subgraphs."
1968 .to_owned(),
1969 None,
1970 )
1971});
1972
1973static ENUM_VALUE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1974 ErrorCodeDefinition::new(
1975 "ENUM_VALUE_MISMATCH".to_owned(),
1976 "An enum type that is used as both an input and output type has a value that is not defined in all the subgraphs that define the enum type.".to_owned(),
1977 None,
1978 )
1979});
1980
1981static EMPTY_MERGED_ENUM_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1982 ErrorCodeDefinition::new(
1983 "EMPTY_MERGED_ENUM_TYPE".to_owned(),
1984 "An enum type has no value common to all the subgraphs that define the type. Merging that type would result in an invalid empty enum type.".to_owned(),
1985 None,
1986 )
1987});
1988
1989static SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES: LazyLock<ErrorCodeDefinition> = LazyLock::new(
1990 || {
1991 ErrorCodeDefinition::new(
1992 "SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES".to_owned(),
1993 "A shareable field return type has mismatched possible runtime types in the subgraphs in which the field is declared. As shared fields must resolve the same way in all subgraphs, this is almost surely a mistake.".to_owned(),
1994 None,
1995 )
1996 },
1997);
1998
1999static SATISFIABILITY_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2000 ErrorCodeDefinition::new(
2001 "SATISFIABILITY_ERROR".to_owned(),
2002 "Subgraphs can be merged, but the resulting supergraph API would have queries that cannot be satisfied by those subgraphs.".to_owned(),
2003 None,
2004 )
2005});
2006
2007static MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED: LazyLock<ErrorCodeDefinition> =
2008 LazyLock::new(|| {
2009 ErrorCodeDefinition::new(
2010 "MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED".to_owned(),
2011 "The maximum number of validation subgraph paths has been exceeded.".to_owned(),
2012 Some(ErrorCodeMetadata {
2013 added_in: "2.8.0",
2014 replaces: &[],
2015 }),
2016 )
2017 });
2018
2019static OVERRIDE_FROM_SELF_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2020 ErrorCodeDefinition::new(
2021 "OVERRIDE_FROM_SELF_ERROR".to_owned(),
2022 "Field with `@override` directive has \"from\" location that references its own subgraph."
2023 .to_owned(),
2024 None,
2025 )
2026});
2027
2028static OVERRIDE_SOURCE_HAS_OVERRIDE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2029 ErrorCodeDefinition::new(
2030 "OVERRIDE_SOURCE_HAS_OVERRIDE".to_owned(),
2031 "Field which is overridden to another subgraph is also marked @override.".to_owned(),
2032 None,
2033 )
2034});
2035
2036static OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2037 || {
2038 ErrorCodeDefinition::new(
2039 "OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE".to_owned(),
2040 "The @override directive cannot be used on external fields, nor to override fields with either @external, @provides, or @requires.".to_owned(),
2041 None,
2042 )
2043 },
2044);
2045
2046static OVERRIDE_ON_INTERFACE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2047 ErrorCodeDefinition::new(
2048 "OVERRIDE_ON_INTERFACE".to_owned(),
2049 "The @override directive cannot be used on the fields of an interface type.".to_owned(),
2050 Some(ErrorCodeMetadata {
2051 added_in: "2.3.0",
2052 replaces: &[],
2053 }),
2054 )
2055});
2056
2057static OVERRIDE_LABEL_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2058 ErrorCodeDefinition::new(
2059 "OVERRIDE_LABEL_INVALID".to_owned(),
2060 r#"The @override directive `label` argument must match the pattern /^[a-zA-Z][a-zA-Z0-9_\-:./]*$/ or /^percent\((\d{1,2}(\.\d{1,8})?|100)\)$/"#.to_owned(),
2061 Some(ErrorCodeMetadata {
2062 added_in: "2.7.0",
2063 replaces: &[],
2064 }),
2065 )
2066});
2067
2068static UNSUPPORTED_FEATURE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2069 ErrorCodeDefinition::new(
2070 "UNSUPPORTED_FEATURE".to_owned(),
2071 "Indicates an error due to feature currently unsupported by federation.".to_owned(),
2072 Some(ErrorCodeMetadata {
2073 added_in: "2.1.0",
2074 replaces: &[],
2075 }),
2076 )
2077});
2078
2079static INVALID_FEDERATION_SUPERGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2080 ErrorCodeDefinition::new(
2081 "INVALID_FEDERATION_SUPERGRAPH".to_owned(),
2082 "Indicates that a schema provided for an Apollo Federation supergraph is not a valid supergraph schema.".to_owned(),
2083 Some(ErrorCodeMetadata {
2084 added_in: "2.1.0",
2085 replaces: &[],
2086 }),
2087 )
2088});
2089
2090static DOWNSTREAM_SERVICE_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2091 ErrorCodeDefinition::new(
2092 "DOWNSTREAM_SERVICE_ERROR".to_owned(),
2093 "Indicates an error in a subgraph service query during query execution in a federated service.".to_owned(),
2094 Some(ErrorCodeMetadata {
2095 added_in: FED1_CODE,
2096 replaces: &[],
2097 }),
2098 )
2099});
2100
2101static DIRECTIVE_COMPOSITION_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2102 ErrorCodeDefinition::new(
2103 "DIRECTIVE_COMPOSITION_ERROR".to_owned(),
2104 "Error when composing custom directives.".to_owned(),
2105 Some(ErrorCodeMetadata {
2106 added_in: "2.1.0",
2107 replaces: &[],
2108 }),
2109 )
2110});
2111
2112static INTERFACE_OBJECT_USAGE_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2113 ErrorCodeDefinition::new(
2114 "INTERFACE_OBJECT_USAGE_ERROR".to_owned(),
2115 "Error in the usage of the @interfaceObject directive.".to_owned(),
2116 Some(ErrorCodeMetadata {
2117 added_in: "2.3.0",
2118 replaces: &[],
2119 }),
2120 )
2121});
2122
2123static INTERFACE_KEY_NOT_ON_IMPLEMENTATION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2124 ErrorCodeDefinition::new(
2125 "INTERFACE_KEY_NOT_ON_IMPLEMENTATION".to_owned(),
2126 "A `@key` is defined on an interface type, but is not defined (or is not resolvable) on at least one of the interface implementations".to_owned(),
2127 Some(ErrorCodeMetadata {
2128 added_in: "2.3.0",
2129 replaces: &[],
2130 }),
2131 )
2132});
2133
2134static INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2135 || {
2136 ErrorCodeDefinition::new(
2137 "INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE".to_owned(),
2138 "A subgraph has a `@key` on an interface type, but that subgraph does not define an implementation (in the supergraph) of that interface".to_owned(),
2139 Some(ErrorCodeMetadata {
2140 added_in: "2.3.0",
2141 replaces: &[],
2142 }),
2143 )
2144 },
2145);
2146
2147static INTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2148 ErrorCodeDefinition::new(
2149 "INTERNAL".to_owned(),
2150 "An internal federation error occured.".to_owned(),
2151 None,
2152 )
2153});
2154
2155static ERROR_CODE_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2156 ErrorCodeDefinition::new(
2157 "ERROR_CODE_MISSING".to_owned(),
2158 "An internal federation error occurred when translating a federation error into an error code".to_owned(),
2159 None,
2160 )
2161});
2162
2163static UNSUPPORTED_FEDERATION_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2164 ErrorCodeDefinition::new(
2165 "UNSUPPORTED_FEDERATION_VERSION".to_owned(),
2166 "Supergraphs composed with federation version 1 are not supported. Please recompose your supergraph with federation version 2 or greater".to_owned(),
2167 None,
2168 )
2169});
2170
2171static UNSUPPORTED_FEDERATION_DIRECTIVE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2172 ErrorCodeDefinition::new(
2173 "UNSUPPORTED_FEDERATION_DIRECTIVE".to_owned(),
2174 "Indicates that the specified specification version is outside of supported range"
2175 .to_owned(),
2176 None,
2177 )
2178});
2179
2180static QUERY_PLAN_COMPLEXITY_EXCEEDED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2181 ErrorCodeDefinition::new(
2182 "QUERY_PLAN_COMPLEXITY_EXCEEDED".to_owned(),
2183 "Indicates that provided query has too many possible ways to generate a plan and cannot be planned in a reasonable amount of time"
2184 .to_owned(),
2185 None,
2186 )
2187});
2188
2189static NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2190 ErrorCodeDefinition::new(
2191 "NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS".to_owned(),
2192 "Indicates that the provided query could not be query planned due to subgraphs being disabled"
2193 .to_owned(),
2194 None,
2195 )
2196});
2197
2198static COST_APPLIED_TO_INTERFACE_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2199 ErrorCodeDefinition::new(
2200 "COST_APPLIED_TO_INTERFACE_FIELD".to_owned(),
2201 "The `@cost` directive must be applied to concrete types".to_owned(),
2202 Some(ErrorCodeMetadata {
2203 added_in: "2.9.2",
2204 replaces: &[],
2205 }),
2206 )
2207});
2208
2209static LIST_SIZE_APPLIED_TO_NON_LIST: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2210 ErrorCodeDefinition::new(
2211 "LIST_SIZE_APPLIED_TO_NON_LIST".to_owned(),
2212 "The `@listSize` directive must be applied to list types".to_owned(),
2213 Some(ErrorCodeMetadata {
2214 added_in: "2.9.2",
2215 replaces: &[],
2216 }),
2217 )
2218});
2219
2220static LIST_SIZE_INVALID_ASSUMED_SIZE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2221 ErrorCodeDefinition::new(
2222 "LIST_SIZE_INVALID_ASSUMED_SIZE".to_owned(),
2223 "The `@listSize` directive assumed size cannot be negative".to_owned(),
2224 Some(ErrorCodeMetadata {
2225 added_in: "2.9.2",
2226 replaces: &[],
2227 }),
2228 )
2229});
2230
2231static LIST_SIZE_INVALID_SLICING_ARGUMENT: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2232 ErrorCodeDefinition::new(
2233 "LIST_SIZE_INVALID_SLICING_ARGUMENT".to_owned(),
2234 "The `@listSize` directive must have existing integer slicing arguments".to_owned(),
2235 Some(ErrorCodeMetadata {
2236 added_in: "2.9.2",
2237 replaces: &[],
2238 }),
2239 )
2240});
2241
2242static LIST_SIZE_INVALID_SIZED_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2243 ErrorCodeDefinition::new(
2244 "LIST_SIZE_INVALID_SIZED_FIELD".to_owned(),
2245 "The `@listSize` directive must reference existing list fields as sized fields".to_owned(),
2246 Some(ErrorCodeMetadata {
2247 added_in: "2.9.2",
2248 replaces: &[],
2249 }),
2250 )
2251});
2252
2253static CONTEXT_NAME_CONTAINS_UNDERSCORE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2254 ErrorCodeDefinition::new(
2255 "CONTEXT_NAME_CONTAINS_UNDERSCORE".to_owned(),
2256 "Context name is invalid.".to_owned(),
2257 Some(ErrorCodeMetadata {
2258 added_in: "2.8.0",
2259 replaces: &[],
2260 }),
2261 )
2262});
2263
2264static CONTEXT_NAME_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2265 ErrorCodeDefinition::new(
2266 "CONTEXT_NAME_INVALID".to_owned(),
2267 "Context name is invalid.".to_owned(),
2268 Some(ErrorCodeMetadata {
2269 added_in: "2.8.0",
2270 replaces: &[],
2271 }),
2272 )
2273});
2274
2275static CONTEXT_NOT_SET: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2276 ErrorCodeDefinition::new(
2277 "CONTEXT_NOT_SET".to_owned(),
2278 "Context is never set for context trying to be used".to_owned(),
2279 Some(ErrorCodeMetadata {
2280 added_in: "2.8.0",
2281 replaces: &[],
2282 }),
2283 )
2284});
2285
2286static NO_CONTEXT_REFERENCED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2287 ErrorCodeDefinition::new(
2288 "NO_CONTEXT_REFERENCED".to_owned(),
2289 "Selection in @fromContext field argument does not reference a context".to_owned(),
2290 Some(ErrorCodeMetadata {
2291 added_in: "2.8.0",
2292 replaces: &[],
2293 }),
2294 )
2295});
2296
2297static NO_SELECTION_FOR_CONTEXT: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2298 ErrorCodeDefinition::new(
2299 "NO_SELECTION_FOR_CONTEXT".to_owned(),
2300 "field parameter in @fromContext must contain a selection set".to_owned(),
2301 Some(ErrorCodeMetadata {
2302 added_in: "2.8.0",
2303 replaces: &[],
2304 }),
2305 )
2306});
2307
2308static CONTEXT_NO_RESOLVABLE_KEY: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2309 ErrorCodeDefinition::new(
2310 "CONTEXT_NO_RESOLVABLE_KEY".to_owned(),
2311 "If an ObjectType uses a @fromContext, at least one of its keys must be resolvable"
2312 .to_owned(),
2313 Some(ErrorCodeMetadata {
2314 added_in: "2.8.0",
2315 replaces: &[],
2316 }),
2317 )
2318});
2319
2320static CONTEXT_SELECTION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2321 ErrorCodeDefinition::new(
2322 "CONTEXT_SELECTION_INVALID".to_owned(),
2323 "The selection set is invalid".to_owned(),
2324 Some(ErrorCodeMetadata {
2325 added_in: "2.8.0",
2326 replaces: &[],
2327 }),
2328 )
2329});
2330
2331static INVALID_TAG_NAME: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2332 ErrorCodeDefinition::new(
2333 "INVALID_TAG_NAME".to_owned(),
2334 "Invalid value for argument \"name\" in application of @tag.".to_owned(),
2335 Some(ErrorCodeMetadata {
2336 added_in: "2.0.0",
2337 replaces: &[],
2338 }),
2339 )
2340});
2341
2342static CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS: LazyLock<ErrorCodeDefinition> =
2343 LazyLock::new(|| {
2344 ErrorCodeDefinition::new(
2345 "CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS".to_owned(),
2346 "Argument on field is marked contextual in only some subgraphs".to_owned(),
2347 Some(ErrorCodeMetadata {
2348 added_in: "2.7.0",
2349 replaces: &[],
2350 }),
2351 )
2352 });
2353
2354static QUERY_ROOT_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2355 ErrorCodeDefinition::new(
2356 "QUERY_ROOT_MISSING".to_owned(),
2357 "The schema has no query root type.".to_owned(),
2358 Some(ErrorCodeMetadata {
2359 added_in: "2.0.0",
2360 replaces: &[],
2361 }),
2362 )
2363});
2364
2365#[derive(Debug, PartialEq, strum_macros::EnumIter)]
2366pub enum ErrorCode {
2367 ErrorCodeMissing,
2368 Internal,
2369 ExtensionWithNoBase,
2370 InvalidGraphQL,
2371 DirectiveDefinitionInvalid,
2372 TypeDefinitionInvalid,
2373 UnsupportedLinkedFeature,
2374 UnknownFederationLinkVersion,
2375 UnknownLinkVersion,
2376 KeyFieldsHasArgs,
2377 ProvidesFieldsHasArgs,
2378 ProvidesFieldsMissingExternal,
2379 RequiresFieldsMissingExternal,
2380 KeyUnsupportedOnInterface,
2381 ProvidesUnsupportedOnInterface,
2382 RequiresUnsupportedOnInterface,
2383 KeyDirectiveInFieldsArgs,
2384 ProvidesDirectiveInFieldsArgs,
2385 RequiresDirectiveInFieldsArgs,
2386 ExternalUnused,
2387 TypeWithOnlyUnusedExternal,
2388 ProvidesOnNonObjectField,
2389 KeyInvalidFieldsType,
2390 ProvidesInvalidFieldsType,
2391 RequiresInvalidFieldsType,
2392 KeyInvalidFields,
2393 ProvidesInvalidFields,
2394 RequiresInvalidFields,
2395 KeyFieldsSelectInvalidType,
2396 RootQueryUsed,
2397 RootMutationUsed,
2398 RootSubscriptionUsed,
2399 InvalidSubgraphName,
2400 NoQueries,
2401 InterfaceFieldNoImplem,
2402 TypeKindMismatch,
2403 ExternalTypeMismatch,
2404 ExternalCollisionWithAnotherDirective,
2405 ExternalArgumentMissing,
2406 ExternalArgumentTypeMismatch,
2407 ExternalArgumentDefaultMismatch,
2408 ExternalOnInterface,
2409 MergedDirectiveApplicationOnExternal,
2410 FieldTypeMismatch,
2411 FieldArgumentTypeMismatch,
2412 InputFieldDefaultMismatch,
2413 FieldArgumentDefaultMismatch,
2414 ExternalMissingOnBase,
2415 InvalidFieldSharing,
2416 InvalidShareableUsage,
2417 InvalidLinkDirectiveUsage,
2418 InvalidLinkIdentifier,
2419 LinkImportNameMismatch,
2420 ReferencedInaccessible,
2421 DefaultValueUsesInaccessible,
2422 QueryRootTypeInaccessible,
2423 RequiredInaccessible,
2424 ImplementedByInaccessible,
2425 DisallowedInaccessible,
2426 OnlyInaccessibleChildren,
2427 RequiredInputFieldMissingInSomeSubgraph,
2428 RequiredArgumentMissingInSomeSubgraph,
2429 EmptyMergedInputType,
2430 InputFieldMergeFailed,
2431 EnumValueMismatch,
2432 EmptyMergedEnumType,
2433 ShareableHasMismatchedRuntimeTypes,
2434 SatisfiabilityError,
2435 MaxValidationSubgraphPathsExceeded,
2436 OverrideFromSelfError,
2437 OverrideSourceHasOverride,
2438 OverrideCollisionWithAnotherDirective,
2439 OverrideOnInterface,
2440 UnsupportedFeature,
2441 InvalidFederationSupergraph,
2442 DownstreamServiceError,
2443 DirectiveCompositionError,
2444 InterfaceObjectUsageError,
2445 InterfaceKeyNotOnImplementation,
2446 InterfaceKeyMissingImplementationType,
2447 UnsupportedFederationVersion,
2448 UnsupportedFederationDirective,
2449 QueryPlanComplexityExceededError,
2450 NoPlanFoundWithDisabledSubgraphs,
2451 CostAppliedToInterfaceField,
2452 ListSizeAppliedToNonList,
2453 ListSizeInvalidAssumedSize,
2454 ListSizeInvalidSlicingArgument,
2455 ListSizeInvalidSizedField,
2456 ContextNameInvalid,
2457 ContextNameContainsUnderscore,
2458 ContextNotSet,
2459 NoContextReferenced,
2460 NoSelectionForContext,
2461 ContextNoResolvableKey,
2462 ContextSelectionInvalid,
2463 InvalidTagName,
2464 OverrideLabelInvalid,
2465 ContextualArgumentNotContextualInAllSubgraphs,
2466 QueryRootMissing,
2467}
2468
2469impl ErrorCode {
2470 pub fn definition(&self) -> &'static ErrorCodeDefinition {
2471 match self {
2472 ErrorCode::Internal => &INTERNAL,
2473 ErrorCode::ExtensionWithNoBase => &EXTENSION_WITH_NO_BASE,
2474 ErrorCode::InvalidGraphQL => &INVALID_GRAPHQL,
2475 ErrorCode::DirectiveDefinitionInvalid => &DIRECTIVE_DEFINITION_INVALID,
2476 ErrorCode::TypeDefinitionInvalid => &TYPE_DEFINITION_INVALID,
2477 ErrorCode::UnsupportedLinkedFeature => &UNSUPPORTED_LINKED_FEATURE,
2478 ErrorCode::UnknownFederationLinkVersion => &UNKNOWN_FEDERATION_LINK_VERSION,
2479 ErrorCode::UnknownLinkVersion => &UNKNOWN_LINK_VERSION,
2480 ErrorCode::KeyFieldsHasArgs => &KEY_FIELDS_HAS_ARGS,
2481 ErrorCode::ProvidesFieldsHasArgs => &PROVIDES_FIELDS_HAS_ARGS,
2482 ErrorCode::ProvidesFieldsMissingExternal => &PROVIDES_FIELDS_MISSING_EXTERNAL,
2483 ErrorCode::RequiresFieldsMissingExternal => &REQUIRES_FIELDS_MISSING_EXTERNAL,
2484 ErrorCode::KeyUnsupportedOnInterface => &KEY_UNSUPPORTED_ON_INTERFACE,
2485 ErrorCode::ProvidesUnsupportedOnInterface => &PROVIDES_UNSUPPORTED_ON_INTERFACE,
2486 ErrorCode::RequiresUnsupportedOnInterface => &REQUIRES_UNSUPPORTED_ON_INTERFACE,
2487 ErrorCode::KeyDirectiveInFieldsArgs => &KEY_DIRECTIVE_IN_FIELDS_ARGS,
2488 ErrorCode::ProvidesDirectiveInFieldsArgs => &PROVIDES_DIRECTIVE_IN_FIELDS_ARGS,
2489 ErrorCode::RequiresDirectiveInFieldsArgs => &REQUIRES_DIRECTIVE_IN_FIELDS_ARGS,
2490 ErrorCode::ExternalUnused => &EXTERNAL_UNUSED,
2491 ErrorCode::ExternalCollisionWithAnotherDirective => {
2492 &EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE
2493 }
2494 ErrorCode::TypeWithOnlyUnusedExternal => &TYPE_WITH_ONLY_UNUSED_EXTERNAL,
2495 ErrorCode::ProvidesOnNonObjectField => &PROVIDES_ON_NON_OBJECT_FIELD,
2496 ErrorCode::KeyInvalidFieldsType => &KEY_INVALID_FIELDS_TYPE,
2497 ErrorCode::ProvidesInvalidFieldsType => &PROVIDES_INVALID_FIELDS_TYPE,
2498 ErrorCode::RequiresInvalidFieldsType => &REQUIRES_INVALID_FIELDS_TYPE,
2499 ErrorCode::KeyInvalidFields => &KEY_INVALID_FIELDS,
2500 ErrorCode::ProvidesInvalidFields => &PROVIDES_INVALID_FIELDS,
2501 ErrorCode::RequiresInvalidFields => &REQUIRES_INVALID_FIELDS,
2502 ErrorCode::KeyFieldsSelectInvalidType => &KEY_FIELDS_SELECT_INVALID_TYPE,
2503 ErrorCode::RootQueryUsed => &ROOT_QUERY_USED,
2504 ErrorCode::RootMutationUsed => &ROOT_MUTATION_USED,
2505 ErrorCode::RootSubscriptionUsed => &ROOT_SUBSCRIPTION_USED,
2506 ErrorCode::InvalidSubgraphName => &INVALID_SUBGRAPH_NAME,
2507 ErrorCode::NoQueries => &NO_QUERIES,
2508 ErrorCode::InterfaceFieldNoImplem => &INTERFACE_FIELD_NO_IMPLEM,
2509 ErrorCode::TypeKindMismatch => &TYPE_KIND_MISMATCH,
2510 ErrorCode::ExternalTypeMismatch => &EXTERNAL_TYPE_MISMATCH,
2511 ErrorCode::ExternalArgumentMissing => &EXTERNAL_ARGUMENT_MISSING,
2512 ErrorCode::ExternalArgumentTypeMismatch => &EXTERNAL_ARGUMENT_TYPE_MISMATCH,
2513 ErrorCode::ExternalArgumentDefaultMismatch => &EXTERNAL_ARGUMENT_DEFAULT_MISMATCH,
2514 ErrorCode::ExternalOnInterface => &EXTERNAL_ON_INTERFACE,
2515 ErrorCode::MergedDirectiveApplicationOnExternal => {
2516 &MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL
2517 }
2518 ErrorCode::FieldTypeMismatch => &FIELD_TYPE_MISMATCH,
2519 ErrorCode::FieldArgumentTypeMismatch => &FIELD_ARGUMENT_TYPE_MISMATCH,
2520 ErrorCode::InputFieldDefaultMismatch => &INPUT_FIELD_DEFAULT_MISMATCH,
2521 ErrorCode::FieldArgumentDefaultMismatch => &FIELD_ARGUMENT_DEFAULT_MISMATCH,
2522 ErrorCode::ExternalMissingOnBase => &EXTERNAL_MISSING_ON_BASE,
2523 ErrorCode::InvalidFieldSharing => &INVALID_FIELD_SHARING,
2524 ErrorCode::InvalidShareableUsage => &INVALID_SHAREABLE_USAGE,
2525 ErrorCode::InvalidLinkDirectiveUsage => &INVALID_LINK_DIRECTIVE_USAGE,
2526 ErrorCode::InvalidLinkIdentifier => &INVALID_LINK_IDENTIFIER,
2527 ErrorCode::LinkImportNameMismatch => &LINK_IMPORT_NAME_MISMATCH,
2528 ErrorCode::ReferencedInaccessible => &REFERENCED_INACCESSIBLE,
2529 ErrorCode::DefaultValueUsesInaccessible => &DEFAULT_VALUE_USES_INACCESSIBLE,
2530 ErrorCode::QueryRootTypeInaccessible => &QUERY_ROOT_TYPE_INACCESSIBLE,
2531 ErrorCode::RequiredInaccessible => &REQUIRED_INACCESSIBLE,
2532 ErrorCode::ImplementedByInaccessible => &IMPLEMENTED_BY_INACCESSIBLE,
2533 ErrorCode::DisallowedInaccessible => &DISALLOWED_INACCESSIBLE,
2534 ErrorCode::OnlyInaccessibleChildren => &ONLY_INACCESSIBLE_CHILDREN,
2535 ErrorCode::RequiredInputFieldMissingInSomeSubgraph => {
2536 &REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH
2537 }
2538 ErrorCode::RequiredArgumentMissingInSomeSubgraph => {
2539 &REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH
2540 }
2541 ErrorCode::EmptyMergedInputType => &EMPTY_MERGED_INPUT_TYPE,
2542 ErrorCode::InputFieldMergeFailed => &INPUT_FIELD_MERGE_FAILED,
2543 ErrorCode::EnumValueMismatch => &ENUM_VALUE_MISMATCH,
2544 ErrorCode::EmptyMergedEnumType => &EMPTY_MERGED_ENUM_TYPE,
2545 ErrorCode::ShareableHasMismatchedRuntimeTypes => {
2546 &SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES
2547 }
2548 ErrorCode::SatisfiabilityError => &SATISFIABILITY_ERROR,
2549 ErrorCode::MaxValidationSubgraphPathsExceeded => {
2550 &MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED
2551 }
2552 ErrorCode::OverrideFromSelfError => &OVERRIDE_FROM_SELF_ERROR,
2553 ErrorCode::OverrideSourceHasOverride => &OVERRIDE_SOURCE_HAS_OVERRIDE,
2554 ErrorCode::OverrideCollisionWithAnotherDirective => {
2555 &OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE
2556 }
2557 ErrorCode::OverrideOnInterface => &OVERRIDE_ON_INTERFACE,
2558 ErrorCode::UnsupportedFeature => &UNSUPPORTED_FEATURE,
2559 ErrorCode::InvalidFederationSupergraph => &INVALID_FEDERATION_SUPERGRAPH,
2560 ErrorCode::DownstreamServiceError => &DOWNSTREAM_SERVICE_ERROR,
2561 ErrorCode::DirectiveCompositionError => &DIRECTIVE_COMPOSITION_ERROR,
2562 ErrorCode::InterfaceObjectUsageError => &INTERFACE_OBJECT_USAGE_ERROR,
2563 ErrorCode::InterfaceKeyNotOnImplementation => &INTERFACE_KEY_NOT_ON_IMPLEMENTATION,
2564 ErrorCode::InterfaceKeyMissingImplementationType => {
2565 &INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE
2566 }
2567 ErrorCode::UnsupportedFederationVersion => &UNSUPPORTED_FEDERATION_VERSION,
2568 ErrorCode::UnsupportedFederationDirective => &UNSUPPORTED_FEDERATION_DIRECTIVE,
2569 ErrorCode::QueryPlanComplexityExceededError => &QUERY_PLAN_COMPLEXITY_EXCEEDED,
2570 ErrorCode::NoPlanFoundWithDisabledSubgraphs => &NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS,
2571 ErrorCode::CostAppliedToInterfaceField => &COST_APPLIED_TO_INTERFACE_FIELD,
2572 ErrorCode::ListSizeAppliedToNonList => &LIST_SIZE_APPLIED_TO_NON_LIST,
2573 ErrorCode::ListSizeInvalidAssumedSize => &LIST_SIZE_INVALID_ASSUMED_SIZE,
2574 ErrorCode::ListSizeInvalidSlicingArgument => &LIST_SIZE_INVALID_SLICING_ARGUMENT,
2575 ErrorCode::ListSizeInvalidSizedField => &LIST_SIZE_INVALID_SIZED_FIELD,
2576 ErrorCode::ContextNameContainsUnderscore => &CONTEXT_NAME_CONTAINS_UNDERSCORE,
2577 ErrorCode::ContextNameInvalid => &CONTEXT_NAME_INVALID,
2578 ErrorCode::ContextNotSet => &CONTEXT_NOT_SET,
2579 ErrorCode::NoContextReferenced => &NO_CONTEXT_REFERENCED,
2580 ErrorCode::NoSelectionForContext => &NO_SELECTION_FOR_CONTEXT,
2581 ErrorCode::ContextNoResolvableKey => &CONTEXT_NO_RESOLVABLE_KEY,
2582 ErrorCode::ContextSelectionInvalid => &CONTEXT_SELECTION_INVALID,
2583 ErrorCode::InvalidTagName => &INVALID_TAG_NAME,
2584 ErrorCode::ErrorCodeMissing => &ERROR_CODE_MISSING,
2585 ErrorCode::OverrideLabelInvalid => &OVERRIDE_LABEL_INVALID,
2586 ErrorCode::ContextualArgumentNotContextualInAllSubgraphs => {
2587 &CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS
2588 }
2589 ErrorCode::QueryRootMissing => &QUERY_ROOT_MISSING,
2590 }
2591 }
2592}