Error type for object_types stage (#814)

<!-- The PR description should answer 2 (maybe 3) important questions:
-->

### What

Break down the big `Error` enum some more. This time, add all errors
from the `object_types` stage into the `ObjectTypesError` enum.

<!-- What is this PR trying to accomplish (and why, if it's not
obvious)? -->

<!-- Consider: do we need to add a changelog entry? -->

### How

Moving code around. Functional no-op.

<!-- How is it trying to accomplish it (what are the implementation
steps)? -->

V3_GIT_ORIGIN_REV_ID: 154d4b40b21365c783d545a23cf18be623f2a3de
This commit is contained in:
Daniel Harvey 2024-07-09 21:20:53 +01:00 committed by hasura-bot
parent 1e8096b1a3
commit f6f4785e7c
9 changed files with 210 additions and 176 deletions

View File

@ -10,9 +10,7 @@ use crate::stages::{
models_graphql, object_boolean_expressions, object_types, relationships, scalar_types,
type_permissions,
};
use crate::types::error::{
Error, RelationshipError, TypeError, TypeMappingValidationError, TypePredicateError,
};
use crate::types::error::{Error, RelationshipError, TypeError, TypePredicateError};
use crate::types::permission::ValueExpression;
use crate::types::subgraph::{ArgumentInfo, Qualified, QualifiedBaseType, QualifiedTypeReference};
@ -255,11 +253,15 @@ pub(crate) fn resolve_value_expression_for_argument(
}
_ => None,
}
.ok_or_else(|| Error::DataConnectorTypeMappingValidationError {
type_name: base_type.clone(),
error: TypeMappingValidationError::PredicateTypeNotFound {
argument_name: argument_name.clone(),
},
.ok_or_else(|| {
Error::from(
object_types::ObjectTypesError::DataConnectorTypeMappingValidationError {
type_name: base_type.clone(),
error: object_types::TypeMappingValidationError::PredicateTypeNotFound {
argument_name: argument_name.clone(),
},
},
)
})?;
let data_connector_field_mappings = object_type_representation
@ -268,14 +270,15 @@ pub(crate) fn resolve_value_expression_for_argument(
.map(|type_mapping| match type_mapping {
object_types::TypeMapping::Object { field_mappings, .. } => field_mappings,
})
.ok_or(Error::DataConnectorTypeMappingValidationError {
.ok_or_else(||Error::from(object_types::ObjectTypesError::DataConnectorTypeMappingValidationError {
type_name: base_type.clone(),
error: TypeMappingValidationError::DataConnectorTypeMappingNotFound {
object_type_name: base_type.clone(),
data_connector_name: data_connector_link.name.clone(),
data_connector_object_type: data_connector_object_type.clone(),
},
})?;
error:
object_types::TypeMappingValidationError::DataConnectorTypeMappingNotFound {
object_type_name: base_type.clone(),
data_connector_name: data_connector_link.name.clone(),
data_connector_object_type: data_connector_object_type.clone(),
},
}))?;
// Get available scalars defined for this data connector
let specific_data_connector_scalars = data_connector_scalars
@ -526,14 +529,14 @@ pub(crate) fn resolve_model_predicate_with_type(
field_mappings, ..
} => field_mappings,
})
.ok_or(Error::DataConnectorTypeMappingValidationError {
.ok_or_else(||Error::from(object_types::ObjectTypesError::DataConnectorTypeMappingValidationError {
type_name: target_typename.clone(),
error: TypeMappingValidationError::DataConnectorTypeMappingNotFound {
error: object_types::TypeMappingValidationError::DataConnectorTypeMappingNotFound {
object_type_name: target_typename.clone(),
data_connector_name: target_source.model.data_connector.name.clone(),
data_connector_object_type: DataConnectorObjectType::from(target_source.model.collection.as_str())
},
})?;
}))?;
// Collect type mappings.
let mut source_type_mappings = BTreeMap::new();

View File

@ -28,11 +28,11 @@ pub struct NdcColumnForComparison {
pub fn store_new_graphql_type(
existing_graphql_types: &mut BTreeSet<ast::TypeName>,
new_graphql_type: Option<&ast::TypeName>,
) -> Result<(), Error> {
) -> Result<(), graphql_config::GraphqlConfigError> {
if let Some(new_graphql_type) = new_graphql_type {
// Fail on conflicting graphql type names
if !(existing_graphql_types.insert(new_graphql_type.clone())) {
return Err(Error::ConflictingGraphQlType {
return Err(graphql_config::GraphqlConfigError::ConflictingGraphQlType {
graphql_type_name: new_graphql_type.clone(),
});
}

View File

@ -1,3 +1,5 @@
use lang_graphql::ast::common as ast;
#[derive(Debug, thiserror::Error)]
pub enum GraphqlConfigError {
#[error("graphql configuration is not defined in supergraph")]
@ -26,4 +28,6 @@ pub enum GraphqlConfigError {
MissingAggregateFilterInputFieldNameInGraphqlConfig,
#[error("\"{name:}\" is not a valid GraphQL name.")]
InvalidGraphQlName { name: String },
#[error("multiple graphql types found with the same name: {graphql_type_name:}")]
ConflictingGraphQlType { graphql_type_name: ast::TypeName },
}

View File

@ -0,0 +1,138 @@
use thiserror::Error;
use crate::stages::graphql_config;
use crate::NDCValidationError;
use open_dds::{
arguments::ArgumentName,
data_connector::{DataConnectorName, DataConnectorObjectType},
types::{CustomTypeName, FieldName},
};
use crate::types::subgraph::Qualified;
#[derive(Debug, Error)]
pub enum ObjectTypesError {
#[error("object type {type_name} could not be found")]
ObjectTypeNotFound {
type_name: Qualified<CustomTypeName>,
},
#[error("the following argument for field {field_name:} in type {type_name:} is defined more than once: {argument_name:}")]
DuplicateArgumentDefinition {
field_name: FieldName,
argument_name: ArgumentName,
type_name: Qualified<CustomTypeName>,
},
#[error("the following type is defined more than once: {name:}")]
DuplicateTypeDefinition { name: Qualified<CustomTypeName> },
#[error("{error:} in object type {type_name:}")]
DataConnectorTypeMappingValidationError {
type_name: Qualified<CustomTypeName>,
error: TypeMappingValidationError,
},
#[error("Multiple mappings have been defined from object {data_connector_object_type:} of data connector {data_connector:}")]
DuplicateDataConnectorObjectTypeMapping {
data_connector: Qualified<DataConnectorName>,
data_connector_object_type: String,
},
#[error("the following field in type {type_name:} is defined more than once: {field_name:}")]
DuplicateFieldDefinition {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
},
#[error("A field named `id` cannot be present in the object type {type_name} when global_id fields are non-empty.")]
IdFieldConflictingGlobalId {
type_name: Qualified<CustomTypeName>,
},
#[error("Unknown field {field_name:} in global_id defined for the type {type_name:}")]
UnknownFieldInGlobalId {
field_name: FieldName,
type_name: Qualified<CustomTypeName>,
},
#[error("empty fields in apollo federation keys defined for the object type {object_type:}")]
EmptyFieldsInApolloFederationConfigForObject {
object_type: Qualified<CustomTypeName>,
},
#[error("unknown field {field_name:} in apollo federation keys defined for the object type {object_type:}")]
UnknownFieldInApolloFederationKey {
field_name: FieldName,
object_type: Qualified<CustomTypeName>,
},
#[error(
"empty keys in apollo federation configuration defined for the object type {object_type:}"
)]
EmptyKeysInApolloFederationConfigForObject {
object_type: Qualified<CustomTypeName>,
},
#[error("{0}")]
GraphqlError(#[from] graphql_config::GraphqlConfigError),
}
#[derive(Error, Debug)]
pub enum TypeMappingValidationError {
#[error("data connector {data_connector:} referenced in type mappings of type {type_name:} is not found")]
UnknownDataConnector {
data_connector: Qualified<DataConnectorName>,
type_name: Qualified<CustomTypeName>,
},
#[error("the type {type_name:} referenced in type mappings has not been defined")]
UnknownSourceType {
type_name: Qualified<CustomTypeName>,
},
#[error(
"the following fields in field mappings of type {type_name:} are unknown: {}",
field_names.join(", ")
)]
UnknownSourceFields {
type_name: Qualified<CustomTypeName>,
field_names: Vec<FieldName>,
},
#[error("unknown target column name {column_name:} for field {field_name:}")]
UnknownTargetColumn {
column_name: String,
field_name: FieldName,
},
#[error(
"the mapping for field {field_name:} of type {type_name:} has been defined more than once"
)]
DuplicateFieldMapping {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
},
#[error(
"the type {unknown_field_type_name:} referenced by the field {field_name:} in type {type_name:} has not been defined"
)]
UnknownFieldType {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
unknown_field_type_name: Qualified<CustomTypeName>,
},
#[error("could not find mappings for {object_type_name:} to the {data_connector_object_type:} on data connector {data_connector_name:}")]
DataConnectorTypeMappingNotFound {
object_type_name: Qualified<CustomTypeName>,
data_connector_name: Qualified<DataConnectorName>,
data_connector_object_type: DataConnectorObjectType,
},
#[error(
"the type {unknown_ndc_type:} is not defined as an object type in the connector's schema. This type is being mapped to by the type {type_name:}"
)]
UnknownNdcType {
type_name: Qualified<CustomTypeName>,
unknown_ndc_type: DataConnectorObjectType,
},
#[error("expected to find a predicate type for argument {argument_name:} but did not")]
PredicateTypeNotFound { argument_name: ArgumentName },
#[error(
"the type {unknown_ndc_field_type_name:} is not defined as an object type in the connector's schema. This type is referenced by the field {ndc_field_name:} in the connector's schema type {ndc_type_name:}, which is mapped to the field {field_name:} in the type {type_name:}"
)]
UnknownNdcFieldObjectType {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
ndc_type_name: String,
ndc_field_name: String,
unknown_ndc_field_type_name: String,
},
#[error("ndc validation error: {0}")]
NDCValidationError(#[from] NDCValidationError),
}

View File

@ -1,22 +1,22 @@
mod error;
pub mod types;
pub use error::{ObjectTypesError, TypeMappingValidationError};
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet};
use open_dds::commands::ArgumentMapping;
use open_dds::{data_connector::DataConnectorColumnName, types::CustomTypeName};
pub use types::{
DataConnectorTypeMappingsForObject, FieldDefinition, FieldMapping, ObjectTypeError,
ObjectTypeRepresentation, ObjectTypeWithTypeMappings, ObjectTypesOutput,
ObjectTypesWithTypeMappings, ResolvedApolloFederationObjectKey,
ResolvedObjectApolloFederationConfig, TypeMapping,
DataConnectorTypeMappingsForObject, FieldDefinition, FieldMapping, ObjectTypeRepresentation,
ObjectTypeWithTypeMappings, ObjectTypesOutput, ObjectTypesWithTypeMappings,
ResolvedApolloFederationObjectKey, ResolvedObjectApolloFederationConfig, TypeMapping,
};
use crate::helpers::ndc_validation::get_underlying_named_type;
use crate::helpers::types::{mk_name, store_new_graphql_type};
use crate::stages::data_connectors;
use crate::types::error::{Error, TypeMappingValidationError};
use crate::types::subgraph::{mk_qualified_type_reference, Qualified};
use indexmap::IndexMap;
@ -26,7 +26,7 @@ use lang_graphql::ast::common as ast;
pub(crate) fn resolve(
metadata_accessor: &open_dds::accessor::MetadataAccessor,
data_connectors: &data_connectors::DataConnectors,
) -> Result<ObjectTypesOutput, Error> {
) -> Result<ObjectTypesOutput, ObjectTypesError> {
let mut object_types = BTreeMap::new();
let mut graphql_types = BTreeSet::new();
let mut global_id_enabled_types = BTreeMap::new();
@ -65,7 +65,7 @@ pub(crate) fn resolve(
data_connectors,
)
.map_err(|type_validation_error| {
Error::DataConnectorTypeMappingValidationError {
ObjectTypesError::DataConnectorTypeMappingValidationError {
type_name: qualified_object_type_name.clone(),
error: type_validation_error,
}
@ -89,7 +89,7 @@ pub(crate) fn resolve(
)
.is_some()
{
return Err(Error::DuplicateTypeDefinition {
return Err(ObjectTypesError::DuplicateTypeDefinition {
name: qualified_object_type_name,
});
}
@ -107,7 +107,7 @@ fn resolve_field(
field: &open_dds::types::FieldDefinition,
subgraph: &str,
qualified_type_name: &Qualified<CustomTypeName>,
) -> Result<FieldDefinition, Error> {
) -> Result<FieldDefinition, ObjectTypesError> {
let mut field_arguments = IndexMap::new();
for argument in &field.arguments {
let field_argument_definition = crate::ArgumentInfo {
@ -118,7 +118,7 @@ fn resolve_field(
.insert(argument.name.clone(), field_argument_definition)
.is_some()
{
return Err(Error::DuplicateArgumentDefinition {
return Err(ObjectTypesError::DuplicateArgumentDefinition {
field_name: field.name.clone(),
argument_name: argument.name.clone(),
type_name: qualified_type_name.clone(),
@ -146,7 +146,7 @@ pub fn resolve_object_type(
Qualified<CustomTypeName>,
Option<Qualified<open_dds::models::ModelName>>,
>,
) -> Result<ObjectTypeRepresentation, Error> {
) -> Result<ObjectTypeRepresentation, ObjectTypesError> {
let mut resolved_fields = IndexMap::new();
let mut resolved_global_id_fields = Vec::new();
@ -158,7 +158,7 @@ pub fn resolve_object_type(
)
.is_some()
{
return Err(Error::DuplicateFieldDefinition {
return Err(ObjectTypesError::DuplicateFieldDefinition {
type_name: qualified_type_name.clone(),
field_name: field.name.clone(),
});
@ -170,7 +170,7 @@ pub fn resolve_object_type(
// Throw error if the object type has a field called id" and has global fields configured.
// Because, when the global id fields are configured, the `id` field will be auto-generated.
if resolved_fields.contains_key("id") {
return Err(Error::IdFieldConflictingGlobalId {
return Err(ObjectTypesError::IdFieldConflictingGlobalId {
type_name: qualified_type_name.clone(),
});
}
@ -184,7 +184,7 @@ pub fn resolve_object_type(
if resolved_fields.contains_key(global_id_field) {
resolved_global_id_fields.push(global_id_field.clone());
} else {
return Err(Error::UnknownFieldInGlobalId {
return Err(ObjectTypesError::UnknownFieldInGlobalId {
field_name: global_id_field.clone(),
type_name: qualified_type_name.clone(),
});
@ -195,7 +195,7 @@ pub fn resolve_object_type(
}
let (graphql_type_name, graphql_input_type_name, apollo_federation_config) =
match object_type_definition.graphql.as_ref() {
None => Ok::<_, Error>((None, None, None)),
None => Ok::<_, ObjectTypesError>((None, None, None)),
Some(graphql) => {
let graphql_type_name = graphql
.type_name
@ -220,10 +220,12 @@ pub fn resolve_object_type(
let mut resolved_key_fields = Vec::new();
for field in &key.fields {
if !resolved_fields.contains_key(field) {
return Err(Error::UnknownFieldInApolloFederationKey {
field_name: field.clone(),
object_type: qualified_type_name.clone(),
});
return Err(
ObjectTypesError::UnknownFieldInApolloFederationKey {
field_name: field.clone(),
object_type: qualified_type_name.clone(),
},
);
}
resolved_key_fields.push(field.clone());
}
@ -231,7 +233,7 @@ pub fn resolve_object_type(
match nonempty::NonEmpty::from_vec(resolved_key_fields) {
None => {
return Err(
Error::EmptyFieldsInApolloFederationConfigForObject {
ObjectTypesError::EmptyFieldsInApolloFederationConfigForObject {
object_type: qualified_type_name.clone(),
},
)
@ -243,9 +245,11 @@ pub fn resolve_object_type(
apollo_federation_entity_enabled_types
.insert(qualified_type_name.clone(), None);
match nonempty::NonEmpty::from_vec(resolved_keys) {
None => Err(Error::EmptyKeysInApolloFederationConfigForObject {
object_type: qualified_type_name.clone(),
}),
None => Err(
ObjectTypesError::EmptyKeysInApolloFederationConfigForObject {
object_type: qualified_type_name.clone(),
},
),
Some(keys) => Ok(Some(ResolvedObjectApolloFederationConfig { keys })),
}
}
@ -257,6 +261,7 @@ pub fn resolve_object_type(
))
}
}?;
store_new_graphql_type(existing_graphql_types, graphql_type_name.as_ref())?;
store_new_graphql_type(existing_graphql_types, graphql_input_type_name.as_ref())?;

View File

@ -1,8 +1,7 @@
use super::error::ObjectTypesError;
use crate::types::subgraph::QualifiedTypeReference;
use crate::{types::error::Error, ArgumentInfo};
use crate::ArgumentInfo;
use indexmap::IndexMap;
use thiserror::Error;
use open_dds::arguments::ArgumentName;
use open_dds::models::ModelName;
use open_dds::types::{CustomTypeName, DataConnectorArgumentName, Deprecated, FieldName};
@ -56,7 +55,7 @@ impl DataConnectorTypeMappingsForObject {
data_connector_name: &Qualified<DataConnectorName>,
data_connector_object_type: &DataConnectorObjectType,
type_mapping: TypeMapping,
) -> Result<(), Error> {
) -> Result<(), ObjectTypesError> {
if self
.0
.entry(data_connector_name.clone())
@ -64,7 +63,7 @@ impl DataConnectorTypeMappingsForObject {
.insert(data_connector_object_type.clone(), type_mapping)
.is_some()
{
return Err(Error::DuplicateDataConnectorObjectTypeMapping {
return Err(ObjectTypesError::DuplicateDataConnectorObjectTypeMapping {
data_connector: data_connector_name.clone(),
data_connector_object_type: data_connector_object_type.to_string(),
});
@ -160,11 +159,3 @@ pub enum TypeMapping {
field_mappings: BTreeMap<FieldName, FieldMapping>,
},
}
#[derive(Debug, Error)]
pub enum ObjectTypeError {
#[error("object type {type_name} could not be found")]
ObjectTypeNotFound {
type_name: Qualified<CustomTypeName>,
},
}

View File

@ -1,10 +1,10 @@
use std::collections::{BTreeMap, BTreeSet};
use lang_graphql::ast::common as ast;
use crate::helpers::types::{mk_name, store_new_graphql_type};
use crate::stages::object_types;
use crate::types::error::Error;
use crate::types::subgraph::Qualified;
use lang_graphql::ast::common as ast;
pub mod types;
pub use types::{ScalarTypeRepresentation, ScalarTypesOutput};
@ -42,9 +42,11 @@ pub fn resolve(
)
.is_some()
{
return Err(Error::DuplicateTypeDefinition {
name: qualified_scalar_type_name,
});
return Err(Error::from(
object_types::ObjectTypesError::DuplicateTypeDefinition {
name: qualified_scalar_type_name,
},
));
}
store_new_graphql_type(&mut graphql_types, graphql_type_name.as_ref())?;
}

View File

@ -24,10 +24,10 @@ impl ObjectTypesWithPermissions {
pub fn get(
&self,
type_name: &Qualified<CustomTypeName>,
) -> Result<&ObjectTypeWithPermissions, object_types::ObjectTypeError> {
) -> Result<&ObjectTypeWithPermissions, object_types::ObjectTypesError> {
self.0
.get(type_name)
.ok_or_else(|| object_types::ObjectTypeError::ObjectTypeNotFound {
.ok_or_else(|| object_types::ObjectTypesError::ObjectTypeNotFound {
type_name: type_name.clone(),
})
}

View File

@ -5,7 +5,6 @@ use crate::stages::{
type_permissions,
};
use crate::types::subgraph::{Qualified, QualifiedTypeName, QualifiedTypeReference};
use lang_graphql::ast::common as ast;
use open_dds::{
aggregates::AggregateExpressionName,
arguments::ArgumentName,
@ -26,23 +25,6 @@ use crate::helpers::{
// TODO: This enum really needs structuring
#[derive(Error, Debug)]
pub enum Error {
#[error("the following type is defined more than once: {name:}")]
DuplicateTypeDefinition { name: Qualified<CustomTypeName> },
#[error("the following field in type {type_name:} is defined more than once: {field_name:}")]
DuplicateFieldDefinition {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
},
#[error("{error:} in object type {type_name:}")]
DataConnectorTypeMappingValidationError {
type_name: Qualified<CustomTypeName>,
error: TypeMappingValidationError,
},
#[error("Multiple mappings have been defined from object {data_connector_object_type:} of data connector {data_connector:}")]
DuplicateDataConnectorObjectTypeMapping {
data_connector: Qualified<DataConnectorName>,
data_connector_object_type: String,
},
#[error("the following model is defined more than once: {name:}")]
DuplicateModelDefinition { name: Qualified<ModelName> },
#[error("'globalIdFields' for type {object_type:} found, but no model found with 'globalIdSource: true' for type {object_type:}")]
@ -214,8 +196,6 @@ pub enum Error {
UnnecessaryFilterInputTypeNameGraphqlConfiguration { model_name: Qualified<ModelName> },
#[error("filter input type name graphql configuration must be specified for model {model_name:} because aggregates are used with it")]
MissingFilterInputTypeNameGraphqlConfiguration { model_name: Qualified<ModelName> },
#[error("multiple graphql types found with the same name: {graphql_type_name:}")]
ConflictingGraphQlType { graphql_type_name: ast::TypeName },
#[error("unknown field {field_name:} in unique identifier defined for model {model_name:}")]
UnknownFieldInUniqueIdentifier {
model_name: Qualified<ModelName>,
@ -226,12 +206,6 @@ pub enum Error {
field_name: FieldName,
object_type: Qualified<CustomTypeName>,
},
#[error(
"empty keys in apollo federation configuration defined for the object type {object_type:}"
)]
EmptyKeysInApolloFederationConfigForObject {
object_type: Qualified<CustomTypeName>,
},
#[error("empty fields in apollo federation keys defined for the object type {object_type:}")]
EmptyFieldsInApolloFederationConfigForObject {
object_type: Qualified<CustomTypeName>,
@ -440,11 +414,6 @@ pub enum Error {
type_name: Qualified<CustomTypeName>,
data_connector: Qualified<DataConnectorName>,
},
#[error("Unknown field {field_name:} in global_id defined for the type {type_name:}")]
UnknownFieldInGlobalId {
field_name: FieldName,
type_name: Qualified<CustomTypeName>,
},
#[error("Model {model_name:} is marked as a global ID source but there are no global id fields present in the related object type {type_name:}")]
NoGlobalFieldsPresentInGlobalIdSource {
type_name: Qualified<CustomTypeName>,
@ -455,10 +424,6 @@ pub enum Error {
type_name: Qualified<CustomTypeName>,
model_name: ModelName,
},
#[error("A field named `id` cannot be present in the object type {type_name} when global_id fields are non-empty.")]
IdFieldConflictingGlobalId {
type_name: Qualified<CustomTypeName>,
},
#[error("Found multiple models {model_1:}, {model_2:} that implement the same object type {object_type:} to be global ID sources.")]
DuplicateModelGlobalIdSource {
model_1: Qualified<ModelName>,
@ -546,18 +511,12 @@ pub enum Error {
AggregateExpressionError(AggregateExpressionError),
#[error("{0}")]
ModelAggregateExpressionError(ModelAggregateExpressionError),
#[error("the following argument for field {field_name:} in type {type_name:} is defined more than once: {argument_name:}")]
DuplicateArgumentDefinition {
field_name: FieldName,
argument_name: ArgumentName,
type_name: Qualified<CustomTypeName>,
},
#[error("{0}")]
DataConnectorError(#[from] data_connectors::DataConnectorError),
#[error("{0}")]
TypePermissionError(type_permissions::TypePermissionError),
#[error("{0}")]
DataConnectorError(#[from] data_connectors::DataConnectorError),
ObjectTypesError(#[from] object_types::ObjectTypesError),
}
#[derive(Debug, Error)]
@ -599,7 +558,7 @@ pub enum ModelAggregateExpressionError {
ModelAggregateObjectTypeError {
model_name: Qualified<ModelName>,
aggregate_expression: Qualified<AggregateExpressionName>,
object_type_error: object_types::ObjectTypeError,
object_type_error: object_types::ObjectTypesError,
},
#[error("{0}")]
OtherError(Box<Error>),
@ -855,74 +814,6 @@ pub enum TypeError {
},
}
#[derive(Error, Debug)]
pub enum TypeMappingValidationError {
#[error("data connector {data_connector:} referenced in type mappings of type {type_name:} is not found")]
UnknownDataConnector {
data_connector: Qualified<DataConnectorName>,
type_name: Qualified<CustomTypeName>,
},
#[error("the type {type_name:} referenced in type mappings has not been defined")]
UnknownSourceType {
type_name: Qualified<CustomTypeName>,
},
#[error(
"the following fields in field mappings of type {type_name:} are unknown: {}",
field_names.join(", ")
)]
UnknownSourceFields {
type_name: Qualified<CustomTypeName>,
field_names: Vec<FieldName>,
},
#[error("unknown target column name {column_name:} for field {field_name:}")]
UnknownTargetColumn {
column_name: String,
field_name: FieldName,
},
#[error(
"the mapping for field {field_name:} of type {type_name:} has been defined more than once"
)]
DuplicateFieldMapping {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
},
#[error(
"the type {unknown_field_type_name:} referenced by the field {field_name:} in type {type_name:} has not been defined"
)]
UnknownFieldType {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
unknown_field_type_name: Qualified<CustomTypeName>,
},
#[error("could not find mappings for {object_type_name:} to the {data_connector_object_type:} on data connector {data_connector_name:}")]
DataConnectorTypeMappingNotFound {
object_type_name: Qualified<CustomTypeName>,
data_connector_name: Qualified<DataConnectorName>,
data_connector_object_type: DataConnectorObjectType,
},
#[error(
"the type {unknown_ndc_type:} is not defined as an object type in the connector's schema. This type is being mapped to by the type {type_name:}"
)]
UnknownNdcType {
type_name: Qualified<CustomTypeName>,
unknown_ndc_type: DataConnectorObjectType,
},
#[error("expected to find a predicate type for argument {argument_name:} but did not")]
PredicateTypeNotFound { argument_name: ArgumentName },
#[error(
"the type {unknown_ndc_field_type_name:} is not defined as an object type in the connector's schema. This type is referenced by the field {ndc_field_name:} in the connector's schema type {ndc_type_name:}, which is mapped to the field {field_name:} in the type {type_name:}"
)]
UnknownNdcFieldObjectType {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
ndc_type_name: String,
ndc_field_name: String,
unknown_ndc_field_type_name: String,
},
#[error("ndc validation error: {0}")]
NDCValidationError(#[from] NDCValidationError),
}
impl From<AggregateExpressionError> for Error {
fn from(val: AggregateExpressionError) -> Self {
Error::AggregateExpressionError(val)