split out RelationshipError (#445)

<!-- Thank you for submitting this PR! :) -->

## Description

More work to break down the giant `Error` type in metadata resolve step.

Functional no-op.

V3_GIT_ORIGIN_REV_ID: 8cfa4ad0bef254e93241d254123910bf3d5357f3
This commit is contained in:
Daniel Harvey 2024-04-08 11:54:51 +01:00 committed by hasura-bot
parent 2a24b3060a
commit 9b8915b5b5
3 changed files with 117 additions and 91 deletions

View File

@ -524,57 +524,6 @@ pub enum Error {
UnknownDataType {
data_type: Qualified<CustomTypeName>,
},
#[error("source field {field_name} in field mapping for relationship {relationship_name} on type {source_type} is unknown.")]
UnknownSourceFieldInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
field_name: FieldName,
},
#[error("target field {field_name} in field mapping for relationship {relationship_name} on type {source_type} to model {model_name} is unknown.")]
UnknownTargetFieldInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
model_name: Qualified<ModelName>,
field_name: FieldName,
},
#[error("target argument {argument_name} in argument mapping for relationship {relationship_name} on type {source_type} to command {command_name} is unknown.")]
UnknownTargetArgumentInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
command_name: Qualified<CommandName>,
argument_name: ArgumentName,
},
#[error("Mapping for source field {field_name} already exists in the relationship {relationship_name} on type {type_name}")]
MappingExistsInRelationship {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
relationship_name: RelationshipName,
},
#[error("Mapping for target argument {argument_name} of command {command_name} already exists in the relationship {relationship_name} on type {type_name}")]
ArgumentMappingExistsInRelationship {
argument_name: ArgumentName,
command_name: Qualified<CommandName>,
relationship_name: RelationshipName,
type_name: Qualified<CustomTypeName>,
},
#[error("No mapping for target command argument {argument_name} in the relationship {relationship_name} on type {type_name}")]
MissingArgumentMappingInRelationship {
type_name: Qualified<CustomTypeName>,
argument_name: ArgumentName,
relationship_name: RelationshipName,
},
#[error("The target data connector {data_connector_name} for relationship {relationship_name} on type {type_name} does not support the variables capability")]
RelationshipTargetDoesNotSupportForEach {
type_name: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
data_connector_name: Qualified<DataConnectorName>,
},
#[error("The target data connector {data_connector_name} for relationship {relationship_name} on type {type_name} has not defined any capabilities")]
NoRelationshipCapabilitiesDefined {
type_name: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
data_connector_name: Qualified<DataConnectorName>,
},
#[error("model {model_name:} with arguments is unsupported as a global ID source")]
ModelWithArgumentsAsGlobalIdSource { model_name: Qualified<ModelName> },
#[error(
@ -629,6 +578,65 @@ pub enum Error {
GraphqlConfigError {
graphql_config_error: GraphqlConfigError,
},
#[error("{relationship_error:}")]
RelationshipError {
relationship_error: RelationshipError,
},
}
#[derive(Debug, Error)]
pub enum RelationshipError {
#[error("source field {field_name} in field mapping for relationship {relationship_name} on type {source_type} is unknown.")]
UnknownSourceFieldInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
field_name: FieldName,
},
#[error("target field {field_name} in field mapping for relationship {relationship_name} on type {source_type} to model {model_name} is unknown.")]
UnknownTargetFieldInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
model_name: Qualified<ModelName>,
field_name: FieldName,
},
#[error("target argument {argument_name} in argument mapping for relationship {relationship_name} on type {source_type} to command {command_name} is unknown.")]
UnknownTargetArgumentInRelationshipMapping {
source_type: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
command_name: Qualified<CommandName>,
argument_name: ArgumentName,
},
#[error("Mapping for source field {field_name} already exists in the relationship {relationship_name} on type {type_name}")]
MappingExistsInRelationship {
type_name: Qualified<CustomTypeName>,
field_name: FieldName,
relationship_name: RelationshipName,
},
#[error("Mapping for target argument {argument_name} of command {command_name} already exists in the relationship {relationship_name} on type {type_name}")]
ArgumentMappingExistsInRelationship {
argument_name: ArgumentName,
command_name: Qualified<CommandName>,
relationship_name: RelationshipName,
type_name: Qualified<CustomTypeName>,
},
#[error("No mapping for target command argument {argument_name} in the relationship {relationship_name} on type {type_name}")]
MissingArgumentMappingInRelationship {
type_name: Qualified<CustomTypeName>,
argument_name: ArgumentName,
relationship_name: RelationshipName,
},
#[error("The target data connector {data_connector_name} for relationship {relationship_name} on type {type_name} does not support the variables capability")]
RelationshipTargetDoesNotSupportForEach {
type_name: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
data_connector_name: Qualified<DataConnectorName>,
},
#[error("The target data connector {data_connector_name} for relationship {relationship_name} on type {type_name} has not defined any capabilities")]
NoRelationshipCapabilitiesDefined {
type_name: Qualified<CustomTypeName>,
relationship_name: RelationshipName,
data_connector_name: Qualified<DataConnectorName>,
},
}
#[derive(Debug, Error)]

View File

@ -1,7 +1,7 @@
use crate::metadata::resolved::argument::get_argument_mappings;
use crate::metadata::resolved::data_connector::get_simple_scalar;
use crate::metadata::resolved::data_connector::{DataConnectorContext, DataConnectorLink};
use crate::metadata::resolved::error::{Error, GraphqlConfigError};
use crate::metadata::resolved::error::{Error, GraphqlConfigError, RelationshipError};
use crate::metadata::resolved::graphql_config::GraphqlConfig;
use crate::metadata::resolved::ndc_validation;
use crate::metadata::resolved::subgraph::{
@ -655,13 +655,16 @@ fn resolve_model_predicate(
target_model_source,
relationship,
)
.map_err(|_| Error::NoRelationshipCapabilitiesDefined {
relationship_name: relationship.name.clone(),
type_name: model.data_type.clone(),
data_connector_name: target_model_source
.data_connector
.name
.clone(),
.map_err(|_| Error::RelationshipError {
relationship_error:
RelationshipError::NoRelationshipCapabilitiesDefined {
relationship_name: relationship.name.clone(),
type_name: model.data_type.clone(),
data_connector_name: target_model_source
.data_connector
.name
.clone(),
},
})?;
let annotation = PredicateRelationshipAnnotation {

View File

@ -1,7 +1,7 @@
use super::command::Command;
use super::data_connector::DataConnectorContext;
use super::data_connector::DataConnectorLink;
use super::error::Error;
use super::error::{Error, RelationshipError};
use super::model::get_ndc_column_for_comparison;
use super::model::Model;
use super::subgraph::Qualified;
@ -129,10 +129,13 @@ fn resolve_relationship_source_mapping<'a>(
}),
[field_access] => {
if !source_type.fields.contains_key(&field_access.field_name) {
return Err(Error::UnknownSourceFieldInRelationshipMapping {
relationship_name: relationship_name.clone(),
source_type: source_type_name.clone(),
field_name: field_access.field_name.clone(),
return Err(Error::RelationshipError {
relationship_error:
RelationshipError::UnknownSourceFieldInRelationshipMapping {
relationship_name: relationship_name.clone(),
source_type: source_type_name.clone(),
field_name: field_access.field_name.clone(),
},
});
};
Ok(field_access)
@ -193,11 +196,13 @@ fn resolve_relationship_mappings_model(
.type_fields
.contains_key(&resolved_relationship_target_mapping.field_name)
{
return Err(Error::UnknownTargetFieldInRelationshipMapping {
relationship_name: relationship.name.clone(),
source_type: source_type_name.clone(),
model_name: target_model.name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
return Err(Error::RelationshipError {
relationship_error: RelationshipError::UnknownTargetFieldInRelationshipMapping {
relationship_name: relationship.name.clone(),
source_type: source_type_name.clone(),
model_name: target_model.name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
},
});
}
@ -231,10 +236,12 @@ fn resolve_relationship_mappings_model(
target_ndc_column,
})
} else {
Err(Error::MappingExistsInRelationship {
type_name: source_type_name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
relationship_name: relationship.name.clone(),
Err(Error::RelationshipError {
relationship_error: RelationshipError::MappingExistsInRelationship {
type_name: source_type_name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
relationship_name: relationship.name.clone(),
},
})
}
}?;
@ -275,21 +282,25 @@ fn resolve_relationship_mappings_command(
// Check if the target argument exists in the target command.
if !target_command.arguments.contains_key(target_argument_name) {
return Err(Error::UnknownTargetArgumentInRelationshipMapping {
relationship_name: relationship.name.clone(),
source_type: source_type_name.clone(),
command_name: target_command.name.clone(),
argument_name: target_argument_name.clone(),
return Err(Error::RelationshipError {
relationship_error: RelationshipError::UnknownTargetArgumentInRelationshipMapping {
relationship_name: relationship.name.clone(),
source_type: source_type_name.clone(),
command_name: target_command.name.clone(),
argument_name: target_argument_name.clone(),
},
});
}
// Check if the target argument is already mapped to a field in the source type.
if !target_command_arguments_hashset_for_validation.insert(&target_argument_name.0) {
return Err(Error::ArgumentMappingExistsInRelationship {
argument_name: target_argument_name.clone(),
command_name: target_command.name.clone(),
relationship_name: relationship.name.clone(),
type_name: source_type_name.clone(),
return Err(Error::RelationshipError {
relationship_error: RelationshipError::ArgumentMappingExistsInRelationship {
argument_name: target_argument_name.clone(),
command_name: target_command.name.clone(),
relationship_name: relationship.name.clone(),
type_name: source_type_name.clone(),
},
});
};
@ -303,10 +314,12 @@ fn resolve_relationship_mappings_command(
argument_name: target_argument_name.clone(),
})
} else {
Err(Error::MappingExistsInRelationship {
type_name: source_type_name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
relationship_name: relationship.name.clone(),
Err(Error::RelationshipError {
relationship_error: RelationshipError::MappingExistsInRelationship {
type_name: source_type_name.clone(),
field_name: resolved_relationship_source_mapping.field_name.clone(),
relationship_name: relationship.name.clone(),
},
})
}
}?;
@ -347,10 +360,12 @@ fn get_relationship_capabilities(
let capabilities = &resolved_data_connector.capabilities.capabilities;
if capabilities.query.variables.is_none() {
return Err(Error::RelationshipTargetDoesNotSupportForEach {
type_name: type_name.clone(),
relationship_name: relationship_name.clone(),
data_connector_name: data_connector.name.clone(),
return Err(Error::RelationshipError {
relationship_error: RelationshipError::RelationshipTargetDoesNotSupportForEach {
type_name: type_name.clone(),
relationship_name: relationship_name.clone(),
data_connector_name: data_connector.name.clone(),
},
});
};