Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4d9628b05 | |||
| 635d31d723 |
53
src/lib.rs
53
src/lib.rs
@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user