1use crate::engine::EvaluationTraceKind;
2use crate::loader::LoaderError;
3use crate::DecisionGraphValidationError;
4use serde::ser::SerializeMap;
5use serde::{Serialize, Serializer};
6use serde_json::Value;
7use std::sync::Arc;
8use thiserror::Error;
9use zen_types::variable::Variable;
10
11#[derive(Debug, Error)]
12pub enum EvaluationError {
13 #[error("Loader error")]
14 LoaderError(LoaderError),
15
16 #[error("{source}")]
17 NodeError {
18 node_id: Arc<str>,
19 trace: Option<Variable>,
20 source: Box<dyn std::error::Error>,
21 },
22
23 #[error("Depth limit exceeded")]
24 DepthLimitExceeded,
25
26 #[error("Invalid graph")]
27 InvalidGraph(DecisionGraphValidationError),
28
29 #[error("Validation failed")]
30 Validation(Value),
31}
32
33impl EvaluationError {
34 pub fn serialize_with_mode<S>(
35 &self,
36 serializer: S,
37 mode: EvaluationTraceKind,
38 ) -> Result<S::Ok, S::Error>
39 where
40 S: Serializer,
41 {
42 let mut map = serializer.serialize_map(None)?;
43
44 match self {
45 EvaluationError::DepthLimitExceeded => {
46 map.serialize_entry("type", "DepthLimitExceeded")?;
47 }
48 EvaluationError::NodeError {
49 node_id,
50 trace,
51 source,
52 } => {
53 map.serialize_entry("type", "NodeError")?;
54 map.serialize_entry("source", &source.to_string())?;
55 map.serialize_entry("nodeId", &node_id)?;
56
57 if let Some(trace) = &trace {
58 map.serialize_entry("trace", &mode.serialize_trace(trace))?;
59 }
60 }
61 EvaluationError::LoaderError(err) => {
62 map.serialize_entry("type", "LoaderError")?;
63 match err {
64 LoaderError::Internal { key, source } => {
65 map.serialize_entry("key", key)?;
66 map.serialize_entry("source", &source.to_string())?;
67 }
68 LoaderError::NotFound(key) => {
69 map.serialize_entry("key", key)?;
70 }
71 }
72 }
73 EvaluationError::InvalidGraph(err) => {
74 map.serialize_entry("type", "InvalidGraph")?;
75 map.serialize_entry("source", err)?;
76 }
77 EvaluationError::Validation(err) => {
78 map.serialize_entry("type", "Validation")?;
79 map.serialize_entry("source", err)?;
80 }
81 }
82
83 map.end()
84 }
85}
86
87impl Serialize for EvaluationError {
88 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89 where
90 S: Serializer,
91 {
92 self.serialize_with_mode(serializer, Default::default())
93 }
94}
95
96impl From<LoaderError> for Box<EvaluationError> {
97 fn from(error: LoaderError) -> Self {
98 Box::new(EvaluationError::LoaderError(error.into()))
99 }
100}
101
102impl From<DecisionGraphValidationError> for Box<EvaluationError> {
103 fn from(error: DecisionGraphValidationError) -> Self {
104 Box::new(EvaluationError::InvalidGraph(error.into()))
105 }
106}