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