Skip to main content

reifydb_function/
error.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use 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>;