Compare commits

...

2 Commits

Author SHA1 Message Date
b4d9628b05 version: 1.0.12 2025-04-15 00:25:39 -04:00
635d31d723 more validation fixes 2025-04-15 00:25:29 -04:00
2 changed files with 40 additions and 15 deletions

View File

@ -4,7 +4,7 @@ pg_module_magic!();
use serde_json::{json, Value}; use serde_json::{json, Value};
use std::{collections::HashMap, sync::RwLock}; use std::{collections::HashMap, sync::RwLock};
use boon::{Compiler, Schemas, ValidationError, SchemaIndex}; use boon::{Compiler, Schemas, ValidationError, SchemaIndex, CompileError};
use lazy_static::lazy_static; use lazy_static::lazy_static;
struct BoonCache { struct BoonCache {
@ -27,9 +27,7 @@ fn cache_json_schema(schema_id: &str, schema: JsonB) -> JsonB {
let mut compiler = Compiler::new(); let mut compiler = Compiler::new();
compiler.enable_format_assertions(); compiler.enable_format_assertions();
let schema_url = format!("urn:jspg:{}", schema_id); if let Err(e) = compiler.add_resource(schema_id, schema_value) {
if let Err(e) = compiler.add_resource(&schema_url, schema_value) {
return JsonB(json!({ return JsonB(json!({
"success": false, "success": false,
"error": { "error": {
@ -40,19 +38,42 @@ fn cache_json_schema(schema_id: &str, schema: JsonB) -> JsonB {
})); }));
} }
match compiler.compile(&schema_url, &mut cache.schemas) { match compiler.compile(schema_id, &mut cache.schemas) {
Ok(sch_index) => { Ok(sch_index) => {
cache.id_to_index.insert(schema_id.to_string(), sch_index); cache.id_to_index.insert(schema_id.to_string(), sch_index);
JsonB(json!({ "success": true })) JsonB(json!({ "success": true }))
} }
Err(e) => JsonB(json!({ Err(e) => {
"success": false, // Enhance error reporting by matching on the CompileError variant
"error": { let error_details = match &e {
"kind": "SchemaCompilationError", CompileError::ValidationError { url, src } => {
"message": format!("Schema compilation failed: {}", e), // Metaschema validation failed - provide more detail
"schema_id": schema_id json!({
} "kind": "SchemaCompilationError",
})), "sub_kind": "ValidationError", // Explicitly state it's a metaschema validation error
"message": format!("Schema failed validation against its metaschema: {}", src),
"schema_id": schema_id,
"failed_at_url": url,
"validation_details": format!("{:?}", src), // Include full debug info of the validation error
})
}
// Handle other potential compilation errors
_ => {
let error_type = format!("{:?}", e).split('(').next().unwrap_or("Unknown").to_string();
json!({
"kind": "SchemaCompilationError",
"sub_kind": error_type, // e.g., "InvalidJsonPointer", "UnsupportedUrlScheme"
"message": format!("Schema compilation failed: {}", e),
"schema_id": schema_id,
"details": format!("{:?}", e), // Generic debug info
})
}
};
JsonB(json!({
"success": false,
"error": error_details
}))
}
} }
} }
@ -218,9 +239,13 @@ mod tests {
assert!(!result.0["success"].as_bool().unwrap()); assert!(!result.0["success"].as_bool().unwrap());
let error_obj = result.0.get("error").expect("Expected top-level 'error' object for compilation failure"); let error_obj = result.0.get("error").expect("Expected top-level 'error' object for compilation failure");
assert_eq!(error_obj.get("kind").and_then(Value::as_str), Some("SchemaCompilationError")); assert_eq!(error_obj.get("kind").and_then(Value::as_str), Some("SchemaCompilationError"));
assert_eq!(error_obj.get("sub_kind").and_then(Value::as_str), Some("ValidationError"), "Expected sub_kind 'ValidationError' for metaschema failure");
assert!(error_obj.get("message").and_then(Value::as_str).is_some(), "Expected 'message' field in error object"); assert!(error_obj.get("message").and_then(Value::as_str).is_some(), "Expected 'message' field in error object");
assert!(error_obj["message"].as_str().unwrap().contains("Schema compilation failed")); // Check content of message assert!(error_obj["message"].as_str().unwrap().contains("Schema failed validation against its metaschema"), "Error message mismatch");
assert_eq!(error_obj.get("schema_id").and_then(Value::as_str), Some(schema_id)); assert_eq!(error_obj.get("schema_id").and_then(Value::as_str), Some(schema_id));
let failed_at_url = error_obj.get("failed_at_url").and_then(Value::as_str).expect("Expected 'failed_at_url' string");
assert!(failed_at_url.ends_with(&format!("{}#", schema_id)), "failed_at_url ('{}') should end with schema_id + '#' ('{}#')", failed_at_url, schema_id);
assert!(error_obj.get("validation_details").and_then(Value::as_str).is_some(), "Expected 'validation_details' field");
} }
#[pg_test] #[pg_test]

View File

@ -1 +1 @@
1.0.11 1.0.12