splitting up errorkind paths to produce multiple drop errors

This commit is contained in:
2025-06-12 17:07:28 -04:00
parent d938058d34
commit 65971d9b93
2 changed files with 578 additions and 42 deletions

View File

@ -155,16 +155,87 @@ fn collect_errors(error: &ValidationError, errors_list: &mut Vec<Error>) {
);
if error.causes.is_empty() && !is_structural {
// This is a leaf error that's not structural
let original_message = format!("{}", error.kind);
let (error_code, human_message) = convert_error_kind(&error.kind);
// Handle errors with multiple fields specially
match &error.kind {
ErrorKind::Required { want } => {
// Create a separate error for each missing required field
let base_path = error.instance_location.to_string();
for missing_field in want {
let field_path = if base_path.is_empty() {
format!("/{}", missing_field)
} else {
format!("{}/{}", base_path, missing_field)
};
errors_list.push(Error {
path: field_path,
code: "REQUIRED_FIELD_MISSING".to_string(),
message: format!("Required field '{}' is missing", missing_field),
cause: format!("property '{}' is required", missing_field),
});
}
}
ErrorKind::Dependency { prop, missing } | ErrorKind::DependentRequired { prop, missing } => {
// Create a separate error for each missing field
let base_path = error.instance_location.to_string();
for missing_field in missing {
let field_path = if base_path.is_empty() {
format!("/{}", missing_field)
} else {
format!("{}/{}", base_path, missing_field)
};
let (error_code, human_message) = match &error.kind {
ErrorKind::Dependency { .. } => (
"DEPENDENCY_FAILED".to_string(),
format!("Field '{}' is required when '{}' is present", missing_field, prop),
),
ErrorKind::DependentRequired { .. } => (
"DEPENDENT_REQUIRED_MISSING".to_string(),
format!("Field '{}' is required when '{}' is present", missing_field, prop),
),
_ => unreachable!(),
};
errors_list.push(Error {
path: field_path,
code: error_code,
message: human_message,
cause: format!("property '{}' required, if '{}' property exists", missing_field, prop),
});
}
}
ErrorKind::AdditionalProperties { got } => {
// Create a separate error for each additional property that's not allowed
let base_path = error.instance_location.to_string();
for extra_prop in got {
let field_path = if base_path.is_empty() {
format!("/{}", extra_prop)
} else {
format!("{}/{}", base_path, extra_prop)
};
errors_list.push(Error {
path: field_path,
code: "ADDITIONAL_PROPERTIES_NOT_ALLOWED".to_string(),
message: format!("Property '{}' is not allowed", extra_prop),
cause: format!("additionalProperty '{}' not allowed", extra_prop),
});
}
}
_ => {
// Handle all other error types normally
let original_message = format!("{}", error.kind);
let (error_code, human_message) = convert_error_kind(&error.kind);
errors_list.push(Error {
path: error.instance_location.to_string(),
code: error_code,
message: human_message,
cause: original_message,
});
errors_list.push(Error {
path: error.instance_location.to_string(),
code: error_code,
message: human_message,
cause: original_message,
});
}
}
} else {
// Recurse into causes
for cause in &error.causes {