Skip to content

Commit

Permalink
move updatable fragment errors into own module
Browse files Browse the repository at this point in the history
Reviewed By: rbalicki2

Differential Revision: D32882405

fbshipit-source-id: c2e67790455c7933dfbc09e3841194b590a9ff88
  • Loading branch information
kassens authored and facebook-github-bot committed Dec 8, 2021
1 parent 6eea5a8 commit a961cf4
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 144 deletions.
131 changes: 0 additions & 131 deletions compiler/crates/graphql-ir/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,6 @@ pub enum ValidationMessage {
#[error("Expected operation to have a name (e.g. 'query <Name>')")]
ExpectedOperationName(),

#[error(
"{pluralized_string} in graphql tags must start with the module name ('{module_name}') and end with '{operation_type_suffix}'. Got '{operation_name}' instead."
)]
InvalidOperationName {
pluralized_string: String,
module_name: String,
operation_type_suffix: String,
operation_name: String,
},

#[error(
"Fragments in graphql tags must start with the module name ('{module_name}'). Got '{fragment_name}' instead."
)]
InvalidFragmentName {
module_name: String,
fragment_name: String,
},

#[error("The schema does not support '{0}' operations")]
UnsupportedOperation(OperationKind),

Expand Down Expand Up @@ -714,121 +696,8 @@ pub enum ValidationMessage {
)]
RequiredRawResponseTypeOnNoInline { fragment_name: StringKey },

// Updatable queries and fragments
#[error("The @updatable directive is yet allowed on fragments.")]
UpdatableNotAllowedOnFragments,

#[error(
"The @{disallowed_directive_name} directive is not allowed in updatable {outer_type_plural}."
)]
UpdatableDisallowOtherDirectives {
disallowed_directive_name: StringKey,
outer_type_plural: &'static str,
},

#[error(
"Only fragments decorated with the @assignable directive can be spread within updatable {outer_type_plural}. You can try adding the @assignable directive to the fragment {fragment_name}."
)]
UpdatableOnlyAssignableFragmentSpreads {
outer_type_plural: &'static str,
fragment_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, if an assignable fragment is spread on a linked field, the fragment's type (`{fragment_type}`) must be equal to or a subtype of the field's type (`{field_type}`)."
)]
UpdatableSpreadOfAssignableFragmentMustBeEqualToOrSubtypeOfOuterField {
outer_type_plural: &'static str,
fragment_type: StringKey,
field_type: StringKey,
},

// Note: conditions do not have a location, hence this awkward phrasing
#[error(
"Within updatable {outer_type_plural}, the directives @include and @skip are not allowed. The directive was found in {operation_or_fragment_name}."
)]
UpdatableNoConditions {
outer_type_plural: &'static str,
operation_or_fragment_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, if a linked field contains an inline fragment spread, it must contain only inline fragment spreads."
)]
UpdatableOnlyInlineFragments { outer_type_plural: &'static str },

#[error(
"Within updatable {outer_type_plural}, inline fragments are only allowed on interfaces or unions, not on concrete types. In updatable queries, each inline fragment must have a type conditions, so no inline fragment would make sense here."
)]
UpdatableInlineFragmentsOnlyOnInterfacesOrUnions { outer_type_plural: &'static str },

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must have a type condition. An inline fragment without a type condition was among the selections of {parent_field_type}."
)]
UpdatableInlineFragmentsRequireTypeConditions {
outer_type_plural: &'static str,
parent_field_type: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must have a type condition narrowing the type to a unique concrete type. `{type_condition}` is not a concrete type."
)]
UpdatableInlineFragmentsTypeConditionsMustBeConcrete {
outer_type_plural: &'static str,
type_condition: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, a single linked field cannot have multiple inline fragments with the same type condition. However, within {parent_field_alias_or_name}, there were multiple inline fragments narrowing the type to `{type_condition}`."
)]
UpdatablePreviouslyEncounteredTypeCondition {
outer_type_plural: &'static str,
type_condition: StringKey,
parent_field_alias_or_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must contain an unaliased typename field. However, within {parent_field_alias_or_name}, there are inline fragments without typename fields."
)]
UpdatableInlineFragmentsMustHaveTypenameFields {
outer_type_plural: &'static str,
parent_field_alias_or_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, an inline fragment cannot occur immediately within another inline fragment. Found within {operation_or_fragment_name}. This is because all inline fragments must have type conditions and narrow the type from an abstract type to a concrete type."
)]
UpdatableNoNestedInlineFragments {
outer_type_plural: &'static str,
operation_or_fragment_name: StringKey,
},

// Assignable fragments
#[error(
"Assignable fragments should contain only a single, unaliased __typename field with no directives."
)]
AssignableOnlyUnaliasedTypenameFieldWithNoDirectives,

#[error("The @{disallowed_directive_name} directive is not allowed on assignable fragments.")]
AssignableDisallowOtherDirectives {
disallowed_directive_name: StringKey,
},

#[error("No fields can have an alias that start with two underscores.")]
NoDoubleUnderscoreAlias,

#[error("Top-level spreads of assignable fragments are not supported.")]
AssignableNoTopLevelFragmentSpreads,

#[error(
"The @{disallowed_directive_name} directive is not allowed on assignable fragment spreads."
)]
AssignableFragmentSpreadNoOtherDirectives {
disallowed_directive_name: StringKey,
},

#[error("Assignable fragments cannot appear within inline fragments")]
AssignableFragmentSpreadNotWithinInlineFragment,
}

#[derive(Clone, Debug, Error, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down
1 change: 0 additions & 1 deletion compiler/crates/js-config-loader/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::process::Output;

use thiserror::Error;

/// Fixed set of validation errors with custom display messages
#[derive(Debug)]
pub struct ConfigError {
pub path: PathBuf,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

use intern::string_key::StringKey;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum ValidationMessage {
#[error(
"The @{disallowed_directive_name} directive is not allowed on assignable fragment spreads."
)]
AssignableFragmentSpreadNoOtherDirectives {
disallowed_directive_name: StringKey,
},

#[error("Assignable fragments cannot appear within inline fragments")]
AssignableFragmentSpreadNotWithinInlineFragment,

#[error("Top-level spreads of assignable fragments are not supported.")]
AssignableNoTopLevelFragmentSpreads,

#[error(
"Assignable fragments should contain only a single, unaliased __typename field with no directives."
)]
AssignableOnlyUnaliasedTypenameFieldWithNoDirectives,

#[error("The @{disallowed_directive_name} directive is not allowed on assignable fragments.")]
AssignableDisallowOtherDirectives {
disallowed_directive_name: StringKey,
},

#[error(
"Only fragments decorated with the @assignable directive can be spread within updatable {outer_type_plural}. You can try adding the @assignable directive to the fragment {fragment_name}."
)]
UpdatableOnlyAssignableFragmentSpreads {
outer_type_plural: &'static str,
fragment_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, if an assignable fragment is spread on a linked field, the fragment's type (`{fragment_type}`) must be equal to or a subtype of the field's type (`{field_type}`)."
)]
UpdatableSpreadOfAssignableFragmentMustBeEqualToOrSubtypeOfOuterField {
outer_type_plural: &'static str,
fragment_type: StringKey,
field_type: StringKey,
},

// Updatable queries and fragments
#[error("The @updatable directive is yet allowed on fragments.")]
UpdatableNotAllowedOnFragments,

#[error(
"The @{disallowed_directive_name} directive is not allowed in updatable {outer_type_plural}."
)]
UpdatableDisallowOtherDirectives {
disallowed_directive_name: StringKey,
outer_type_plural: &'static str,
},

// Note: conditions do not have a location, hence this awkward phrasing
#[error(
"Within updatable {outer_type_plural}, the directives @include and @skip are not allowed. The directive was found in {operation_or_fragment_name}."
)]
UpdatableNoConditions {
outer_type_plural: &'static str,
operation_or_fragment_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, if a linked field contains an inline fragment spread, it must contain only inline fragment spreads."
)]
UpdatableOnlyInlineFragments { outer_type_plural: &'static str },

#[error(
"Within updatable {outer_type_plural}, inline fragments are only allowed on interfaces or unions, not on concrete types. In updatable queries, each inline fragment must have a type conditions, so no inline fragment would make sense here."
)]
UpdatableInlineFragmentsOnlyOnInterfacesOrUnions { outer_type_plural: &'static str },

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must have a type condition. An inline fragment without a type condition was among the selections of {parent_field_type}."
)]
UpdatableInlineFragmentsRequireTypeConditions {
outer_type_plural: &'static str,
parent_field_type: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must have a type condition narrowing the type to a unique concrete type. `{type_condition}` is not a concrete type."
)]
UpdatableInlineFragmentsTypeConditionsMustBeConcrete {
outer_type_plural: &'static str,
type_condition: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, a single linked field cannot have multiple inline fragments with the same type condition. However, within {parent_field_alias_or_name}, there were multiple inline fragments narrowing the type to `{type_condition}`."
)]
UpdatablePreviouslyEncounteredTypeCondition {
outer_type_plural: &'static str,
type_condition: StringKey,
parent_field_alias_or_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, each inline fragment spread must contain an unaliased typename field. However, within {parent_field_alias_or_name}, there are inline fragments without typename fields."
)]
UpdatableInlineFragmentsMustHaveTypenameFields {
outer_type_plural: &'static str,
parent_field_alias_or_name: StringKey,
},

#[error(
"Within updatable {outer_type_plural}, an inline fragment cannot occur immediately within another inline fragment. Found within {operation_or_fragment_name}. This is because all inline fragments must have type conditions and narrow the type from an abstract type to a concrete type."
)]
UpdatableNoNestedInlineFragments {
outer_type_plural: &'static str,
operation_or_fragment_name: StringKey,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
* LICENSE file in the root directory of this source tree.
*/

mod errors;
mod validate_assignable_directive;
mod validate_updatable_directive;

use self::errors::ValidationMessage;
use common::{Diagnostic, DiagnosticsResult, Location, NamedItem, WithLocation};
use graphql_ir::{
Condition, FragmentSpread, InlineFragment, LinkedField, OperationDefinition, Program,
ScalarField, Selection, Transformed, Transformer, ValidationMessage,
ScalarField, Selection, Transformed, Transformer,
};
use intern::string_key::{Intern, StringKey};
use lazy_static::lazy_static;
use schema::{FieldID, Schema};
use std::sync::Arc;
pub use validate_assignable_directive::validate_assignable_directive;
pub use validate_updatable_directive::{validate_updatable_directive, UPDATABLE_DIRECTIVE_NAME};

lazy_static! {
static ref ASSIGNABLE_DIRECTIVE: StringKey = "assignable".intern();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

use super::ValidationMessage;
use common::{Diagnostic, DiagnosticsResult, NamedItem};
use graphql_ir::{FragmentDefinition, Program, Selection, ValidationMessage, Validator};
use graphql_ir::{FragmentDefinition, Program, Selection, Validator};
use intern::string_key::{Intern, StringKey};
use lazy_static::lazy_static;
use schema::Schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

use std::collections::HashSet;

use super::validate_assignable_directive::ASSIGNABLE_DIRECTIVE_NAME;
use super::ValidationMessage;
use crate::assignable_fragment_spread::validate_assignable_directive::ASSIGNABLE_DIRECTIVE_NAME;
use common::{Diagnostic, DiagnosticsResult, Location, NamedItem};
use errors::{validate, validate_map};
use graphql_ir::{
Condition, Directive, Field, FragmentDefinition, FragmentSpread, InlineFragment, LinkedField,
OperationDefinition, Program, Selection, ValidationMessage, Validator,
OperationDefinition, Program, Selection, Validator,
};
use intern::string_key::{Intern, StringKey};
use lazy_static::lazy_static;
Expand Down
5 changes: 4 additions & 1 deletion compiler/crates/relay-transforms/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ pub use crate::errors::ValidationMessage;
pub use applied_fragment_name::get_applied_fragment_name;
pub use apply_fragment_arguments::apply_fragment_arguments;
pub use apply_transforms::{apply_transforms, Programs};
pub use assignable_fragment_spread::transform_assignable_fragment_spreads;
pub use assignable_fragment_spread::{
transform_assignable_fragment_spreads, validate_assignable_directive,
validate_updatable_directive, UPDATABLE_DIRECTIVE_NAME,
};
pub use client_edges::{
client_edges, preserve_client_edge_backing_ids, preserve_client_edge_selections,
ClientEdgeMetadata, CLIENT_EDGE_GENERATED_FRAGMENT_KEY, CLIENT_EDGE_METADATA_KEY,
Expand Down
4 changes: 0 additions & 4 deletions compiler/crates/relay-transforms/src/validations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mod deprecated_fields;
mod disallow_circular_no_inline_fragments;
mod disallow_reserved_aliases;
mod disallow_typename_on_root;
pub(crate) mod validate_assignable_directive;
mod validate_connections;
mod validate_global_variables;
mod validate_module_names;
Expand All @@ -21,13 +20,11 @@ mod validate_selection_conflict;
mod validate_server_only_directives;
mod validate_unused_fragment_variables;
mod validate_unused_variables;
mod validate_updatable_directive;

pub use deprecated_fields::{deprecated_fields, deprecated_fields_for_executable_definition};
pub use disallow_circular_no_inline_fragments::disallow_circular_no_inline_fragments;
pub use disallow_reserved_aliases::disallow_reserved_aliases;
pub use disallow_typename_on_root::disallow_typename_on_root;
pub use validate_assignable_directive::validate_assignable_directive;
pub use validate_connections::validate_connections;
pub use validate_global_variables::validate_global_variables;
pub use validate_module_names::{extract_module_name, validate_module_names};
Expand All @@ -39,4 +36,3 @@ pub use validate_selection_conflict::validate_selection_conflict;
pub use validate_server_only_directives::validate_server_only_directives;
pub use validate_unused_fragment_variables::validate_unused_fragment_variables;
pub use validate_unused_variables::validate_unused_variables;
pub use validate_updatable_directive::{validate_updatable_directive, UPDATABLE_DIRECTIVE_NAME};
Loading

0 comments on commit a961cf4

Please sign in to comment.