surrealdb/api/err/
mod.rs

1use crate::{api::Response, Value};
2use serde::Serialize;
3use std::path::PathBuf;
4use std::{convert::Infallible, io};
5use surrealdb_core::dbs::capabilities::{ParseFuncTargetError, ParseNetTargetError};
6use thiserror::Error;
7
8/// An error originating from a remote SurrealDB database
9#[derive(Error, Debug)]
10#[non_exhaustive]
11pub enum Error {
12	/// There was an error processing the query
13	#[error("{0}")]
14	Query(String),
15
16	/// There was an error processing a remote HTTP request
17	#[error("There was an error processing a remote HTTP request: {0}")]
18	Http(String),
19
20	/// There was an error processing a remote WS request
21	#[error("There was an error processing a remote WS request: {0}")]
22	Ws(String),
23
24	/// The specified scheme does not match any supported protocol or storage engine
25	#[error("Unsupported protocol or storage engine, `{0}`")]
26	Scheme(String),
27
28	/// Tried to run database queries without initialising the connection first
29	#[error("Connection uninitialised")]
30	ConnectionUninitialised,
31
32	/// Tried to call `connect` on an instance already connected
33	#[error("Already connected")]
34	AlreadyConnected,
35
36	/// `Query::bind` not called with an object nor a key/value tuple
37	#[error("Invalid bindings: {0}")]
38	InvalidBindings(Value),
39
40	/// Tried to use a range query on a record ID
41	#[error("Tried to add a range to an record-id resource")]
42	RangeOnRecordId,
43
44	/// Tried to use a range query on an object
45	#[error("Tried to add a range to an object resource")]
46	RangeOnObject,
47
48	/// Tried to use a range query on an array
49	#[error("Tried to add a range to an array resource")]
50	RangeOnArray,
51
52	/// Tried to use a range query on an edge or edges
53	#[error("Tried to add a range to an edge resource")]
54	RangeOnEdges,
55
56	/// Tried to use a range query on an existing range
57	#[error("Tried to add a range to a resource which was already a range")]
58	RangeOnRange,
59
60	/// Tried to use a range query on an unspecified resource
61	#[error("Tried to add a range to an unspecified resource")]
62	RangeOnUnspecified,
63
64	/// Tried to use `table:id` syntax as a method parameter when `(table, id)` should be used instead
65	#[error("Table name `{table}` contained a colon (:), this is dissallowed to avoid confusion with record-id's try `Table(\"{table}\")` instead.")]
66	TableColonId {
67		table: String,
68	},
69
70	/// Duplicate request ID
71	#[error("Duplicate request ID: {0}")]
72	DuplicateRequestId(i64),
73
74	/// Invalid request
75	#[error("Invalid request: {0}")]
76	InvalidRequest(String),
77
78	/// Invalid params
79	#[error("Invalid params: {0}")]
80	InvalidParams(String),
81
82	/// Internal server error
83	#[error("Internal error: {0}")]
84	InternalError(String),
85
86	/// Parse error
87	#[error("Parse error: {0}")]
88	ParseError(String),
89
90	/// Invalid semantic version
91	#[error("Invalid semantic version: {0}")]
92	InvalidSemanticVersion(String),
93
94	/// Invalid URL
95	#[error("Invalid URL: {0}")]
96	InvalidUrl(String),
97
98	/// Failed to convert a `sql::Value` to `T`
99	#[error("Failed to convert `{value}` to `T`: {error}")]
100	FromValue {
101		value: Value,
102		error: String,
103	},
104
105	/// Failed to deserialize a binary response
106	#[error("Failed to deserialize a binary response: {error}")]
107	ResponseFromBinary {
108		binary: Vec<u8>,
109		error: bincode::Error,
110	},
111
112	/// Failed to serialize `sql::Value` to JSON string
113	#[error("Failed to serialize `{value}` to JSON string: {error}")]
114	ToJsonString {
115		value: Value,
116		error: String,
117	},
118
119	/// Failed to deserialize from JSON string to `sql::Value`
120	#[error("Failed to deserialize `{string}` to sql::Value: {error}")]
121	FromJsonString {
122		string: String,
123		error: String,
124	},
125
126	/// Invalid namespace name
127	#[error("Invalid namespace name: {0:?}")]
128	InvalidNsName(String),
129
130	/// Invalid database name
131	#[error("Invalid database name: {0:?}")]
132	InvalidDbName(String),
133
134	/// File open error
135	#[error("Failed to open `{path}`: {error}")]
136	FileOpen {
137		path: PathBuf,
138		error: io::Error,
139	},
140
141	/// File read error
142	#[error("Failed to read `{path}`: {error}")]
143	FileRead {
144		path: PathBuf,
145		error: io::Error,
146	},
147
148	/// Tried to take only a single result when the query returned multiple records
149	#[error("Tried to take only a single result from a query that contains multiple")]
150	LossyTake(Response),
151
152	/// The protocol or storage engine being used does not support backups on the architecture
153	/// it's running on
154	#[error("The protocol or storage engine does not support backups on this architecture")]
155	BackupsNotSupported,
156
157	/// The version of the server is not compatible with the versions supported by this SDK
158	#[error("server version `{server_version}` does not match the range supported by the client `{supported_versions}`")]
159	VersionMismatch {
160		server_version: semver::Version,
161		supported_versions: String,
162	},
163
164	/// The build metadata of the server is older than the minimum supported by this SDK
165	#[error("server build `{server_metadata}` is older than the minimum supported build `{supported_metadata}`")]
166	BuildMetadataMismatch {
167		server_metadata: semver::BuildMetadata,
168		supported_metadata: semver::BuildMetadata,
169	},
170
171	/// The protocol or storage engine being used does not support live queries on the architecture
172	/// it's running on
173	#[error("The protocol or storage engine does not support live queries on this architecture")]
174	LiveQueriesNotSupported,
175
176	/// Tried to use a range query on an object
177	#[error("Live queries on objects not supported")]
178	LiveOnObject,
179
180	/// Tried to use a range query on an array
181	#[error("Live queries on arrays not supported")]
182	LiveOnArray,
183
184	/// Tried to use a range query on an edge or edges
185	#[error("Live queries on edges not supported")]
186	LiveOnEdges,
187
188	/// Tried to use a range query on an unspecified resource
189	#[error("Live queries on unspecified resource not supported")]
190	LiveOnUnspecified,
191
192	/// Tried to access a query statement as a live query when it isn't a live query
193	#[error("Query statement {0} is not a live query")]
194	NotLiveQuery(usize),
195
196	/// Tried to access a query statement falling outside the bounds of the statements supplied
197	#[error("Query statement {0} is out of bounds")]
198	QueryIndexOutOfBounds(usize),
199
200	/// Called `Response::take` or `Response::stream` on a query response more than once
201	#[error("Tried to take a query response that has already been taken")]
202	ResponseAlreadyTaken,
203
204	/// Tried to insert on an object
205	#[error("Insert queries on objects are not supported")]
206	InsertOnObject,
207
208	/// Tried to insert on an array
209	#[error("Insert queries on arrays are not supported")]
210	InsertOnArray,
211
212	/// Tried to insert on an edge or edges
213	#[error("Insert queries on edges are not supported")]
214	InsertOnEdges,
215
216	/// Tried to insert on an edge or edges
217	#[error("Insert queries on ranges are not supported")]
218	InsertOnRange,
219
220	/// Tried to insert on an unspecified resource with no data
221	#[error("Insert queries on unspecified resource with no data are not supported")]
222	InsertOnUnspecified,
223
224	#[error("{0}")]
225	InvalidNetTarget(#[from] ParseNetTargetError),
226
227	#[error("{0}")]
228	InvalidFuncTarget(#[from] ParseFuncTargetError),
229
230	#[error("failed to serialize Value: {0}")]
231	SerializeValue(String),
232	#[error("failed to deserialize Value: {0}")]
233	DeSerializeValue(String),
234
235	#[error("failed to serialize to a Value: {0}")]
236	Serializer(String),
237	#[error("failed to deserialize from a Value: {0}")]
238	Deserializer(String),
239
240	/// Tried to convert an value which contained something like for example a query or future.
241	#[error("tried to convert from a value which contained non-primitive values to a value which only allows primitive values.")]
242	RecievedInvalidValue,
243}
244
245impl serde::ser::Error for Error {
246	fn custom<T>(msg: T) -> Self
247	where
248		T: std::fmt::Display,
249	{
250		Error::SerializeValue(msg.to_string())
251	}
252}
253
254impl serde::de::Error for Error {
255	fn custom<T>(msg: T) -> Self
256	where
257		T: std::fmt::Display,
258	{
259		Error::DeSerializeValue(msg.to_string())
260	}
261}
262
263impl From<Infallible> for crate::Error {
264	fn from(_: Infallible) -> Self {
265		unreachable!()
266	}
267}
268
269impl From<ParseNetTargetError> for crate::Error {
270	fn from(e: ParseNetTargetError) -> Self {
271		Self::Api(Error::from(e))
272	}
273}
274
275impl From<ParseFuncTargetError> for crate::Error {
276	fn from(e: ParseFuncTargetError) -> Self {
277		Self::Api(Error::from(e))
278	}
279}
280
281#[cfg(feature = "protocol-http")]
282impl From<reqwest::Error> for crate::Error {
283	fn from(e: reqwest::Error) -> Self {
284		Self::Api(Error::Http(e.to_string()))
285	}
286}
287
288#[cfg(all(feature = "protocol-ws", not(target_arch = "wasm32")))]
289#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", not(target_arch = "wasm32")))))]
290impl From<tokio_tungstenite::tungstenite::Error> for crate::Error {
291	fn from(error: tokio_tungstenite::tungstenite::Error) -> Self {
292		Self::Api(Error::Ws(error.to_string()))
293	}
294}
295
296impl<T> From<channel::SendError<T>> for crate::Error {
297	fn from(error: channel::SendError<T>) -> Self {
298		Self::Api(Error::InternalError(error.to_string()))
299	}
300}
301
302impl From<channel::RecvError> for crate::Error {
303	fn from(error: channel::RecvError) -> Self {
304		Self::Api(Error::InternalError(error.to_string()))
305	}
306}
307
308impl From<url::ParseError> for crate::Error {
309	fn from(error: url::ParseError) -> Self {
310		Self::Api(Error::InternalError(error.to_string()))
311	}
312}
313
314#[cfg(all(feature = "protocol-ws", target_arch = "wasm32"))]
315#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", target_arch = "wasm32"))))]
316impl From<ws_stream_wasm::WsErr> for crate::Error {
317	fn from(error: ws_stream_wasm::WsErr) -> Self {
318		Self::Api(Error::Ws(error.to_string()))
319	}
320}
321
322#[cfg(all(feature = "protocol-ws", target_arch = "wasm32"))]
323#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", target_arch = "wasm32"))))]
324impl From<pharos::PharErr> for crate::Error {
325	fn from(error: pharos::PharErr) -> Self {
326		Self::Api(Error::Ws(error.to_string()))
327	}
328}
329
330impl Serialize for Error {
331	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
332	where
333		S: serde::Serializer,
334	{
335		serializer.serialize_str(self.to_string().as_str())
336	}
337}