Skip to main content

apollo_federation/error/
mod.rs

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