reifydb_routine/function/
error.rs1use reifydb_type::{
5 error::{Diagnostic, Error, IntoDiagnostic, TypeError},
6 fragment::Fragment,
7 value::r#type::Type,
8};
9
10#[derive(Debug, thiserror::Error)]
11pub enum FunctionError {
12 #[error("function {} expects {expected} arguments, got {actual}", function.text())]
13 ArityMismatch {
14 function: Fragment,
15 expected: usize,
16 actual: usize,
17 },
18
19 #[error("function {} argument {} has invalid type: got {actual:?}", function.text(), argument_index + 1)]
20 InvalidArgumentType {
21 function: Fragment,
22 argument_index: usize,
23 expected: Vec<Type>,
24 actual: Type,
25 },
26
27 #[error("function {} execution failed: {reason}", function.text())]
28 ExecutionFailed {
29 function: Fragment,
30 reason: String,
31 },
32
33 #[error("generator function '{}' not found", function.text())]
34 NotFound {
35 function: Fragment,
36 },
37
38 #[error(transparent)]
39 Wrapped(Box<Error>),
40}
41
42impl From<Error> for FunctionError {
43 fn from(err: Error) -> Self {
44 FunctionError::Wrapped(Box::new(err))
45 }
46}
47
48impl From<TypeError> for FunctionError {
49 fn from(err: TypeError) -> Self {
50 FunctionError::Wrapped(Box::new(Error::from(err)))
51 }
52}
53
54impl FunctionError {
55 pub fn with_context(self, function: Fragment) -> Error {
59 match self {
60 FunctionError::Wrapped(inner) => {
61 let name = function.text().to_string();
62 let mut cause = inner.0;
63 cause.with_fragment(function.clone());
64 Error(Diagnostic {
65 code: "FUNCTION_007".to_string(),
66 statement: None,
67 message: format!("Function {} execution failed", name),
68 column: None,
69 fragment: function,
70 label: Some("execution failed".to_string()),
71 help: Some("Check function arguments and data".to_string()),
72 notes: vec![],
73 cause: Some(Box::new(cause)),
74 operator_chain: None,
75 })
76 }
77 other => Error(other.into_diagnostic()),
78 }
79 }
80}
81
82impl From<FunctionError> for Error {
83 fn from(err: FunctionError) -> Self {
84 Error(err.into_diagnostic())
85 }
86}
87
88impl IntoDiagnostic for FunctionError {
89 fn into_diagnostic(self) -> Diagnostic {
90 match self {
91 FunctionError::ArityMismatch {
92 function,
93 expected,
94 actual,
95 } => {
96 let name = function.text().to_string();
97 Diagnostic {
98 code: "FUNCTION_002".to_string(),
99 statement: None,
100 message: format!(
101 "Function {} expects {} arguments, got {}",
102 name, expected, actual
103 ),
104 column: None,
105 fragment: function,
106 label: Some("wrong number of arguments".to_string()),
107 help: Some(format!(
108 "Provide exactly {} arguments to function {}",
109 expected, name
110 )),
111 notes: vec![],
112 cause: None,
113 operator_chain: None,
114 }
115 }
116 FunctionError::InvalidArgumentType {
117 function,
118 argument_index,
119 expected,
120 actual,
121 } => {
122 let name = function.text().to_string();
123 let expected_types =
124 expected.iter().map(|t| format!("{:?}", t)).collect::<Vec<_>>().join(", ");
125 Diagnostic {
126 code: "FUNCTION_004".to_string(),
127 statement: None,
128 message: format!(
129 "Function {} argument {} has invalid type: expected one of [{}], got {:?}",
130 name,
131 argument_index + 1,
132 expected_types,
133 actual
134 ),
135 column: None,
136 fragment: function,
137 label: Some("invalid argument type".to_string()),
138 help: Some(format!("Provide an argument of type: {}", expected_types)),
139 notes: vec![],
140 cause: None,
141 operator_chain: None,
142 }
143 }
144 FunctionError::ExecutionFailed {
145 function,
146 reason,
147 } => {
148 let name = function.text().to_string();
149 Diagnostic {
150 code: "FUNCTION_007".to_string(),
151 statement: None,
152 message: format!("Function {} execution failed: {}", name, reason),
153 column: None,
154 fragment: function,
155 label: Some("execution failed".to_string()),
156 help: Some("Check function arguments and data".to_string()),
157 notes: vec![],
158 cause: None,
159 operator_chain: None,
160 }
161 }
162 FunctionError::NotFound {
163 function,
164 } => {
165 let name = function.text().to_string();
166 Diagnostic {
167 code: "FUNCTION_009".to_string(),
168 statement: None,
169 message: format!("Generator function '{}' not found", name),
170 column: None,
171 fragment: function,
172 label: Some("unknown generator function".to_string()),
173 help: Some("Check the generator function name and ensure it is registered"
174 .to_string()),
175 notes: vec![],
176 cause: None,
177 operator_chain: None,
178 }
179 }
180 FunctionError::Wrapped(err) => err.0,
181 }
182 }
183}
184
185pub type ScalarFunctionError = FunctionError;
186pub type AggregateFunctionError = FunctionError;
187pub type GeneratorFunctionError = FunctionError;
188
189pub type ScalarFunctionResult<T> = Result<T, FunctionError>;
190pub type AggregateFunctionResult<T> = Result<T, FunctionError>;
191pub type GeneratorFunctionResult<T> = Result<T, FunctionError>;