mf_engine/
error.rs

1use 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}