more error cleanup

This commit is contained in:
2025-04-16 00:38:04 -04:00
parent 6ca00f27e9
commit 499bf68b2a
2 changed files with 251 additions and 146 deletions

View File

@ -80,47 +80,56 @@ fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
match cache.id_to_index.get(schema_id) {
None => JsonB(json!({
"success": false,
"error": {
"message": format!("Schema with id '{}' not found in cache", schema_id)
}
"errors": [json!({
"message": format!("Schema with id '{}' not found in cache", schema_id),
"schema_path": "",
"instance_path": ""
})]
})),
Some(sch_index) => {
let instance_value: Value = instance.0;
match cache.schemas.validate(&instance_value, *sch_index) {
Ok(_) => JsonB(json!({ "success": true })),
Err(validation_error) => {
let error = format_validation_error(&validation_error);
JsonB(json!({
"success": false,
"error": error
}))
// Directly use the result of format_validation_error
// which now includes the top-level success indicator and flat error list
JsonB(format_validation_error(&validation_error))
}
}
}
}
}
fn format_validation_error(error: &ValidationError) -> Value {
let nested_errors: Vec<Value> = error.causes.iter().map(format_validation_error).collect();
// Use specific message for leaf errors, generic for containers
let message = if error.causes.is_empty() {
let default_message = format!("{}", error); // Use boon's default message for specific errors
// Try to strip the "at '<path>': " prefix
if let Some(start_index) = default_message.find("': ") {
default_message[start_index + 3..].to_string()
// Recursively collects leaf errors into a flat list
fn collect_leaf_errors(error: &ValidationError, errors_list: &mut Vec<Value>) {
if error.causes.is_empty() {
let default_message = format!("{}", error);
let message = if let Some(start_index) = default_message.find("': ") {
default_message[start_index + 3..].to_string()
} else {
default_message // Fallback if pattern not found
}
default_message
};
errors_list.push(json!({
"message": message,
"schema_path": error.schema_url.to_string(),
"instance_path": error.instance_location.to_string(),
}));
} else {
"Validation failed due to nested errors".to_string() // Generic message for container errors
};
for cause in &error.causes {
collect_leaf_errors(cause, errors_list);
}
}
}
// Formats validation errors into a flat list JSON structure
fn format_validation_error(error: &ValidationError) -> Value {
let mut all_errors = Vec::new();
collect_leaf_errors(error, &mut all_errors);
json!({
"message": message,
"schema_path": error.schema_url.to_string(), // Use schema_url directly
"instance_path": error.instance_location.to_string(),
"error": nested_errors // Recursively format nested errors
"success": false,
"errors": all_errors // Flat list of specific errors
})
}
@ -166,4 +175,4 @@ pub mod pg_test {
#[pg_schema]
mod tests {
include!("tests.rs");
}
}