moduforge_rules_engine/
error.rs1use crate::handler::graph::DecisionGraphValidationError;
2use crate::handler::node::NodeError;
3use crate::loader::LoaderError;
4use jsonschema::{ErrorIterator, ValidationError};
5use serde::ser::SerializeMap;
6use serde::{Serialize, Serializer};
7use serde_json::{Map, Value};
8use std::iter::once;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12pub enum EvaluationError {
13 #[error("加载器错误")]
14 LoaderError(Box<LoaderError>),
15
16 #[error("节点错误")]
17 NodeError(Box<NodeError>),
18
19 #[error("深度限制超出")]
20 DepthLimitExceeded,
21
22 #[error("无效的图")]
23 InvalidGraph(Box<DecisionGraphValidationError>),
24
25 #[error("验证失败")]
26 Validation(Box<Value>),
27}
28
29impl Serialize for EvaluationError {
30 fn serialize<S>(
31 &self,
32 serializer: S,
33 ) -> Result<S::Ok, S::Error>
34 where
35 S: Serializer,
36 {
37 let mut map = serializer.serialize_map(None)?;
38 match self {
39 EvaluationError::DepthLimitExceeded => {
40 map.serialize_entry("type", "DepthLimitExceeded")?;
41 },
42 EvaluationError::NodeError(err) => {
43 map.serialize_entry("type", "NodeError")?;
44 map.serialize_entry("nodeId", &err.node_id)?;
45 map.serialize_entry("source", &err.source.to_string())?;
46
47 if let Some(trace) = &err.trace {
48 map.serialize_entry("trace", &trace)?;
49 }
50 },
51 EvaluationError::LoaderError(err) => {
52 map.serialize_entry("type", "LoaderError")?;
53 match err.as_ref() {
54 LoaderError::Internal { key, source } => {
55 map.serialize_entry("key", key)?;
56 map.serialize_entry("source", &source.to_string())?;
57 },
58 LoaderError::NotFound(key) => {
59 map.serialize_entry("key", key)?;
60 },
61 }
62 },
63 EvaluationError::InvalidGraph(err) => {
64 map.serialize_entry("type", "InvalidGraph")?;
65 map.serialize_entry("source", err)?;
66 },
67 EvaluationError::Validation(err) => {
68 map.serialize_entry("type", "Validation")?;
69 map.serialize_entry("source", err)?;
70 },
71 }
72
73 map.end()
74 }
75}
76
77impl From<LoaderError> for Box<EvaluationError> {
78 fn from(error: LoaderError) -> Self {
79 Box::new(EvaluationError::LoaderError(error.into()))
80 }
81}
82
83impl From<Box<LoaderError>> for Box<EvaluationError> {
84 fn from(error: Box<LoaderError>) -> Self {
85 Box::new(EvaluationError::LoaderError(error))
86 }
87}
88
89impl From<NodeError> for Box<EvaluationError> {
90 fn from(error: NodeError) -> Self {
91 Box::new(EvaluationError::NodeError(error.into()))
92 }
93}
94
95impl From<Box<NodeError>> for Box<EvaluationError> {
96 fn from(error: Box<NodeError>) -> Self {
97 Box::new(EvaluationError::NodeError(error))
98 }
99}
100
101impl From<DecisionGraphValidationError> for Box<EvaluationError> {
102 fn from(error: DecisionGraphValidationError) -> Self {
103 Box::new(EvaluationError::InvalidGraph(error.into()))
104 }
105}
106
107#[derive(Serialize)]
108#[serde(rename_all = "camelCase")]
109struct ValidationErrorJson {
110 path: String,
111 message: String,
112}
113
114impl<'a> From<ValidationError<'a>> for ValidationErrorJson {
115 fn from(value: ValidationError<'a>) -> Self {
116 ValidationErrorJson {
117 path: value.instance_path.to_string(),
118 message: format!("{}", value),
119 }
120 }
121}
122
123impl<'a> From<ErrorIterator<'a>> for Box<EvaluationError> {
124 fn from(error_iter: ErrorIterator<'a>) -> Self {
125 let errors: Vec<ValidationErrorJson> =
126 error_iter.into_iter().map(From::from).collect();
127
128 let mut json_map = Map::new();
129 json_map.insert(
130 "errors".to_string(),
131 serde_json::to_value(errors).unwrap_or_default(),
132 );
133
134 Box::new(EvaluationError::Validation(Box::new(Value::Object(json_map))))
135 }
136}
137
138impl<'a> From<ValidationError<'a>> for Box<EvaluationError> {
139 fn from(value: ValidationError<'a>) -> Self {
140 let iterator: ErrorIterator<'a> = Box::new(once(value));
141 Box::<EvaluationError>::from(iterator)
142 }
143}