From 384315d7fd55b8dc15fb01f3d7145a58592aeb4d Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Wed, 25 May 2022 17:01:56 -0700 Subject: [PATCH] Report schema location for invalid types (#3924) Summary: With Client Edges, if you specify an `edge_to` with an invalid type name we were previously reporting an error at a generated location. Screen Shot 2022-05-25 at 8 39 24 AM This also ensures we provide a correct error location when you type a field type in a client schema extension. Pull Request resolved: https://github.com/facebook/relay/pull/3924 Test Plan: Create a Relay Resolver with `edge_to Foo` and see an error message that points to the correct location: Screen Shot 2022-05-25 at 8 28 44 AM Reviewed By: voideanvalue Differential Revision: D36667389 Pulled By: captbaritone fbshipit-source-id: 700414188c75f3043c889cf3fa7dce6841168da7 --- compiler/crates/schema/src/in_memory/mod.rs | 19 ++++++++++--------- .../fixtures/invalid-type-reference.expected | 9 +++++---- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/crates/schema/src/in_memory/mod.rs b/compiler/crates/schema/src/in_memory/mod.rs index 76ed7c17ee6c0..83b76bd93d511 100644 --- a/compiler/crates/schema/src/in_memory/mod.rs +++ b/compiler/crates/schema/src/in_memory/mod.rs @@ -1348,7 +1348,7 @@ impl InMemorySchema { .iter() .map(|field_def| { let arguments = self.build_arguments(&field_def.arguments)?; - let type_ = self.build_type_reference(&field_def.type_)?; + let type_ = self.build_type_reference(&field_def.type_, field_location_key)?; let directives = self.build_directive_values(&field_def.directives); let description = field_def.description.as_ref().map(|desc| desc.value); Ok(self.build_field(Field { @@ -1390,7 +1390,7 @@ impl InMemorySchema { } let arguments = self.build_arguments(&field_def.arguments)?; let directives = self.build_directive_values(&field_def.directives); - let type_ = self.build_type_reference(&field_def.type_)?; + let type_ = self.build_type_reference(&field_def.type_, source_location_key)?; let description = field_def.description.as_ref().map(|desc| desc.value); field_ids.push(self.build_field(Field { name: WithLocation::new(field_location, field_name), @@ -1465,22 +1465,23 @@ impl InMemorySchema { fn build_type_reference( &mut self, ast_type: &TypeAnnotation, + source_location: SourceLocationKey, ) -> DiagnosticsResult { Ok(match ast_type { TypeAnnotation::Named(named_type) => TypeReference::Named( *self.type_map.get(&named_type.name.value).ok_or_else(|| { vec![Diagnostic::error( SchemaError::UndefinedType(named_type.name.value), - Location::generated(), + Location::new(source_location, named_type.name.span), )] })?, ), - TypeAnnotation::NonNull(of_type) => { - TypeReference::NonNull(Box::new(self.build_type_reference(&of_type.type_)?)) - } - TypeAnnotation::List(of_type) => { - TypeReference::List(Box::new(self.build_type_reference(&of_type.type_)?)) - } + TypeAnnotation::NonNull(of_type) => TypeReference::NonNull(Box::new( + self.build_type_reference(&of_type.type_, source_location)?, + )), + TypeAnnotation::List(of_type) => TypeReference::List(Box::new( + self.build_type_reference(&of_type.type_, source_location)?, + )), }) } diff --git a/compiler/crates/schema/tests/build_schema/fixtures/invalid-type-reference.expected b/compiler/crates/schema/tests/build_schema/fixtures/invalid-type-reference.expected index a05464c2b7af9..530b19980660f 100644 --- a/compiler/crates/schema/tests/build_schema/fixtures/invalid-type-reference.expected +++ b/compiler/crates/schema/tests/build_schema/fixtures/invalid-type-reference.expected @@ -7,7 +7,8 @@ type User { ==================================== ERROR ==================================== ✖︎ Reference to undefined type 'Email'. - :1:1 - 1 │ # expected-to-throw - │ ^ - 2 │ + :4:12 + 3 │ type User { + 4 │ emails: [Email!]! + │ ^^^^^ + 5 │ }