1use reifydb_type::{
5 error::{Diagnostic, Error, IntoDiagnostic},
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<FunctionError> for Error {
49 fn from(err: FunctionError) -> Self {
50 Error(err.into_diagnostic())
51 }
52}
53
54impl IntoDiagnostic for FunctionError {
55 fn into_diagnostic(self) -> Diagnostic {
56 match self {
57 FunctionError::ArityMismatch {
58 function,
59 expected,
60 actual,
61 } => {
62 let name = function.text().to_string();
63 Diagnostic {
64 code: "FUNCTION_002".to_string(),
65 statement: None,
66 message: format!(
67 "Function {} expects {} arguments, got {}",
68 name, expected, actual
69 ),
70 column: None,
71 fragment: function,
72 label: Some("wrong number of arguments".to_string()),
73 help: Some(format!(
74 "Provide exactly {} arguments to function {}",
75 expected, name
76 )),
77 notes: vec![],
78 cause: None,
79 operator_chain: None,
80 }
81 }
82 FunctionError::InvalidArgumentType {
83 function,
84 argument_index,
85 expected,
86 actual,
87 } => {
88 let name = function.text().to_string();
89 let expected_types =
90 expected.iter().map(|t| format!("{:?}", t)).collect::<Vec<_>>().join(", ");
91 Diagnostic {
92 code: "FUNCTION_004".to_string(),
93 statement: None,
94 message: format!(
95 "Function {} argument {} has invalid type: expected one of [{}], got {:?}",
96 name,
97 argument_index + 1,
98 expected_types,
99 actual
100 ),
101 column: None,
102 fragment: function,
103 label: Some("invalid argument type".to_string()),
104 help: Some(format!("Provide an argument of type: {}", expected_types)),
105 notes: vec![],
106 cause: None,
107 operator_chain: None,
108 }
109 }
110 FunctionError::ExecutionFailed {
111 function,
112 reason,
113 } => {
114 let name = function.text().to_string();
115 Diagnostic {
116 code: "FUNCTION_007".to_string(),
117 statement: None,
118 message: format!("Function {} execution failed: {}", name, reason),
119 column: None,
120 fragment: function,
121 label: Some("execution failed".to_string()),
122 help: Some("Check function arguments and data".to_string()),
123 notes: vec![],
124 cause: None,
125 operator_chain: None,
126 }
127 }
128 FunctionError::NotFound {
129 function,
130 } => {
131 let name = function.text().to_string();
132 Diagnostic {
133 code: "FUNCTION_009".to_string(),
134 statement: None,
135 message: format!("Generator function '{}' not found", name),
136 column: None,
137 fragment: function,
138 label: Some("unknown generator function".to_string()),
139 help: Some("Check the generator function name and ensure it is registered"
140 .to_string()),
141 notes: vec![],
142 cause: None,
143 operator_chain: None,
144 }
145 }
146 FunctionError::Wrapped(err) => err.0,
147 }
148 }
149}
150
151pub type ScalarFunctionError = FunctionError;
152pub type AggregateFunctionError = FunctionError;
153pub type GeneratorFunctionError = FunctionError;
154
155pub type ScalarFunctionResult<T> = Result<T, FunctionError>;
156pub type AggregateFunctionResult<T> = Result<T, FunctionError>;
157pub type GeneratorFunctionResult<T> = Result<T, FunctionError>;