jspg error refactoring checkpoint
This commit is contained in:
@ -28,6 +28,8 @@ use serde_json::Value;
|
||||
use indexmap::IndexMap;
|
||||
use std::sync::Arc;
|
||||
use r#type::Type;
|
||||
use std::collections::HashMap;
|
||||
use crate::drop::{Drop, Error, ErrorDetails};
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct Database {
|
||||
@ -57,13 +59,7 @@ impl Database {
|
||||
|
||||
let mut errors = Vec::new();
|
||||
|
||||
if let Err(e) = compose::compose(&mut val, &mut errors) {
|
||||
errors.push(crate::drop::Error {
|
||||
code: "COMPOSE_FAILED".to_string(),
|
||||
message: format!("Fatal error during trait composition: {}", e),
|
||||
details: crate::drop::ErrorDetails::default(),
|
||||
});
|
||||
}
|
||||
compose::compose(&mut val, &mut errors);
|
||||
|
||||
if let serde_json::Value::Object(mut map) = val {
|
||||
if let Some(serde_json::Value::Array(arr)) = map.remove("enums") {
|
||||
@ -78,10 +74,13 @@ impl Database {
|
||||
db.enums.insert(def.name.clone(), def);
|
||||
}
|
||||
Err(e) => {
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "DATABASE_ENUM_PARSE_FAILED".to_string(),
|
||||
message: format!("Failed to parse database enum '{}': {}", name, e),
|
||||
details: crate::drop::ErrorDetails {
|
||||
values: Some(HashMap::from([
|
||||
("enum".to_string(), name.clone()),
|
||||
("reason".to_string(), e.to_string()),
|
||||
])),
|
||||
details: ErrorDetails {
|
||||
context: Some(serde_json::json!(name)),
|
||||
..Default::default()
|
||||
},
|
||||
@ -103,10 +102,13 @@ impl Database {
|
||||
db.types.insert(def.name.clone(), def);
|
||||
}
|
||||
Err(e) => {
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "DATABASE_TYPE_PARSE_FAILED".to_string(),
|
||||
message: format!("Failed to parse database type '{}': {}", name, e),
|
||||
details: crate::drop::ErrorDetails {
|
||||
values: Some(HashMap::from([
|
||||
("type".to_string(), name.clone()),
|
||||
("reason".to_string(), e.to_string()),
|
||||
])),
|
||||
details: ErrorDetails {
|
||||
context: Some(serde_json::json!(name)),
|
||||
..Default::default()
|
||||
},
|
||||
@ -132,10 +134,13 @@ impl Database {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "DATABASE_RELATION_PARSE_FAILED".to_string(),
|
||||
message: format!("Failed to parse database relation '{}': {}", constraint, e),
|
||||
details: crate::drop::ErrorDetails {
|
||||
values: Some(HashMap::from([
|
||||
("relation".to_string(), constraint.clone()),
|
||||
("reason".to_string(), e.to_string()),
|
||||
])),
|
||||
details: ErrorDetails {
|
||||
context: Some(serde_json::json!(constraint)),
|
||||
..Default::default()
|
||||
},
|
||||
@ -157,10 +162,13 @@ impl Database {
|
||||
db.puncs.insert(def.name.clone(), def);
|
||||
}
|
||||
Err(e) => {
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "DATABASE_PUNC_PARSE_FAILED".to_string(),
|
||||
message: format!("Failed to parse database punc '{}': {}", name, e),
|
||||
details: crate::drop::ErrorDetails {
|
||||
values: Some(HashMap::from([
|
||||
("punc".to_string(), name.clone()),
|
||||
("reason".to_string(), e.to_string()),
|
||||
])),
|
||||
details: ErrorDetails {
|
||||
context: Some(serde_json::json!(name)),
|
||||
..Default::default()
|
||||
},
|
||||
@ -173,9 +181,9 @@ impl Database {
|
||||
|
||||
db.compile(&mut errors);
|
||||
let drop = if errors.is_empty() {
|
||||
crate::drop::Drop::success()
|
||||
Drop::success()
|
||||
} else {
|
||||
crate::drop::Drop::with_errors(errors)
|
||||
Drop::with_errors(errors)
|
||||
};
|
||||
(db, drop)
|
||||
}
|
||||
@ -443,7 +451,7 @@ impl Database {
|
||||
|
||||
// Abort relation discovery early if no hierarchical inheritance match was found
|
||||
if matching_rels.is_empty() {
|
||||
let mut details = crate::drop::ErrorDetails {
|
||||
let mut details = ErrorDetails {
|
||||
path: Some(path.to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
@ -451,12 +459,13 @@ impl Database {
|
||||
details.schema = Some(sid.to_string());
|
||||
}
|
||||
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "EDGE_MISSING".to_string(),
|
||||
message: format!(
|
||||
"No database relation exists between '{}' and '{}' for property '{}'",
|
||||
parent_type, child_type, prop_name
|
||||
),
|
||||
values: Some(HashMap::from([
|
||||
("parent_type".to_string(), parent_type.to_string()),
|
||||
("child_type".to_string(), child_type.to_string()),
|
||||
("property_name".to_string(), prop_name.to_string()),
|
||||
])),
|
||||
details,
|
||||
});
|
||||
return None;
|
||||
@ -542,7 +551,7 @@ impl Database {
|
||||
// we must abort rather than silently guessing. Returning None prevents arbitrary SQL generation
|
||||
// and forces a clean structural error for the architect.
|
||||
if !resolved {
|
||||
let mut details = crate::drop::ErrorDetails {
|
||||
let mut details = ErrorDetails {
|
||||
path: Some(path.to_string()),
|
||||
context: serde_json::to_value(&matching_rels).ok(),
|
||||
cause: Some("Multiple conflicting constraints found matching prefixes".to_string()),
|
||||
@ -552,12 +561,13 @@ impl Database {
|
||||
details.schema = Some(sid.to_string());
|
||||
}
|
||||
|
||||
errors.push(crate::drop::Error {
|
||||
errors.push(Error {
|
||||
code: "AMBIGUOUS_TYPE_RELATIONS".to_string(),
|
||||
message: format!(
|
||||
"Ambiguous database relation between '{}' and '{}' for property '{}'",
|
||||
parent_type, child_type, prop_name
|
||||
),
|
||||
values: Some(HashMap::from([
|
||||
("parent_type".to_string(), parent_type.to_string()),
|
||||
("child_type".to_string(), child_type.to_string()),
|
||||
("property_name".to_string(), prop_name.to_string()),
|
||||
])),
|
||||
details,
|
||||
});
|
||||
return None;
|
||||
|
||||
Reference in New Issue
Block a user