surrealdb_expr/expr/
error.rs1#![deny(clippy::wildcard_enum_match_arm)]
13
14use common::{LeafError, internal_todo};
15use surrealdb_types::{Error as TypesError, SerializationError, ToSql, ValidationError};
16
17use crate::expr::operation::PatchError;
18use crate::val::{CastError, CoerceError, Value};
19
20#[derive(Debug, thiserror::Error)]
22pub enum Error {
23 #[error("Cannot use {} in a CONTENT clause", value.to_sql())]
25 InvalidContent {
26 value: Value,
27 },
28
29 #[error("Cannot use {} in a MERGE clause", value.to_sql())]
31 InvalidMerge {
32 value: Value,
33 },
34
35 #[error(
37 "The value is nested too deeply. A value may be nested at most {max} levels; reduce the nesting or split the data across records"
38 )]
39 ValueTooDeep {
40 max: usize,
41 },
42
43 #[error("The JSON Patch contains invalid operations. {0}")]
45 InvalidPatch(PatchError),
46
47 #[error(
49 "Given test operation failed for JSON Patch. Expected `{expected}`, but got `{got}` instead."
50 )]
51 PatchTest {
52 expected: String,
53 got: String,
54 },
55
56 #[error("Incorrect arguments for function {name}(). {message}")]
59 InvalidFunctionArguments {
60 name: String,
61 message: String,
62 },
63
64 #[error("Incorrect arguments for method {name}(). {message}")]
67 InvalidMethodArguments {
68 name: String,
69 message: String,
70 },
71
72 #[error("Invalid regular expression: {0:?}")]
74 InvalidRegex(String),
75
76 #[error("Found {value} for the Record ID but this is not a valid id")]
78 IdInvalid {
79 value: String,
80 },
81
82 #[error("Found {value} for the Record ID but this is not a valid table name")]
84 TbInvalid {
85 value: String,
86 },
87
88 #[error("{variant} destructuring method is not supported here")]
90 UnsupportedDestructure {
91 variant: String,
92 },
93
94 #[error("{0}")]
96 Coerce(#[from] CoerceError),
97
98 #[error("{0}")]
100 Cast(#[from] CastError),
101
102 #[error("Cannot perform addition with '{0}' and '{1}'")]
104 TryAdd(String, String),
105
106 #[error("Cannot perform subtraction with '{0}' and '{1}'")]
108 TrySub(String, String),
109
110 #[error("Cannot perform multiplication with '{0}' and '{1}'")]
112 TryMul(String, String),
113
114 #[error("Cannot perform division with '{0}' and '{1}'")]
116 TryDiv(String, String),
117
118 #[error("Cannot perform remainder with '{0}' and '{1}'")]
120 TryRem(String, String),
121
122 #[error("Cannot raise the value '{0}' with '{1}'")]
124 TryPow(String, String),
125
126 #[error("Cannot negate the value '{0}'")]
128 TryNeg(String),
129
130 #[error("Cannot extend '{0}' as it is not an array")]
132 TryExtend(String),
133
134 #[error("Cannot convert from '{0}' to '{1}'")]
136 TryFrom(String, &'static str),
137
138 #[error("Timestamp arithmetic error: {0}")]
141 TimestampOverflow(String),
142
143 #[error("Serialization error: {0}")]
145 Serialization(String),
146
147 #[error("Failed to compute: \"{0}\", as the operation results in an arithmetic overflow.")]
149 ArithmeticOverflow(String),
150
151 #[error("Failed to compute: \"{0}\", as the operation results in a negative value.")]
153 ArithmeticNegativeOverflow(String),
154
155 #[error("The string could not be parsed into a bytesize")]
156 InvalidBytesize,
157}
158
159impl LeafError for Error {
160 fn map_kind(self, message: String) -> TypesError {
161 match self {
162 Error::InvalidContent {
164 value,
165 } => TypesError::validation(
166 message,
167 ValidationError::InvalidContent {
168 value: value.to_sql(),
169 },
170 ),
171 Error::InvalidMerge {
172 value,
173 } => TypesError::validation(
174 message,
175 ValidationError::InvalidMerge {
176 value: value.to_sql(),
177 },
178 ),
179 Error::InvalidPatch(_) => TypesError::validation(message, None),
180 Error::ValueTooDeep {
183 ..
184 } => TypesError::validation(message, None),
185 Error::Coerce(_) => TypesError::validation(message, None),
186 Error::Cast(_) => TypesError::validation(message, None),
187 Error::TryAdd(..)
188 | Error::TrySub(..)
189 | Error::TryMul(..)
190 | Error::TryDiv(..)
191 | Error::TryRem(..)
192 | Error::TryPow(..)
193 | Error::TryNeg(_)
194 | Error::TryExtend(_) => TypesError::validation(message, None),
195 Error::TryFrom(..) => TypesError::validation(message, None),
196
197 Error::Serialization(..) => {
199 TypesError::serialization(message, SerializationError::Serialization)
200 }
201
202 Error::TimestampOverflow(..) => TypesError::internal(message),
205
206 Error::PatchTest {
211 ..
212 }
213 | Error::InvalidFunctionArguments {
214 ..
215 }
216 | Error::InvalidMethodArguments {
217 ..
218 }
219 | Error::InvalidRegex(_)
220 | Error::IdInvalid {
221 ..
222 }
223 | Error::TbInvalid {
224 ..
225 }
226 | Error::UnsupportedDestructure {
227 ..
228 }
229 | Error::ArithmeticOverflow(_)
230 | Error::ArithmeticNegativeOverflow(_)
231 | Error::InvalidBytesize => internal_todo(message),
232 }
233 }
234}
235
236impl Error {
237 pub fn is_ignorable(&self) -> bool {
246 matches!(
247 self,
248 Error::Coerce(_)
249 | Error::Cast(_)
250 | Error::InvalidFunctionArguments { .. }
251 | Error::TryAdd(..)
252 | Error::TrySub(..)
253 | Error::TryMul(..)
254 | Error::TryDiv(..)
255 | Error::TryPow(..)
256 | Error::TryNeg(..)
257 | Error::TryExtend(..)
258 )
259 }
260}
261
262impl From<regex::Error> for Error {
263 fn from(error: regex::Error) -> Self {
264 Error::InvalidRegex(error.to_string())
265 }
266}