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