sqlx_exasol_impl/responses/
error.rs

1use std::{borrow::Cow, error::Error, fmt::Display};
2
3use serde::Deserialize;
4use sqlx_core::error::{DatabaseError, ErrorKind};
5
6/// An error directly issued by the Exasol database. Implementor of [`DatabaseError`].
7// Represents the [`super::ExaResult::Error`] variant.
8#[derive(Debug, Deserialize)]
9pub struct ExaDatabaseError {
10    text: String,
11    #[serde(rename = "sqlCode")]
12    code: String,
13}
14
15impl Display for ExaDatabaseError {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(f, "Exasol error {}: {}", self.code, self.text)
18    }
19}
20
21impl Error for ExaDatabaseError {}
22
23impl DatabaseError for ExaDatabaseError {
24    fn message(&self) -> &str {
25        &self.text
26    }
27
28    fn code(&self) -> Option<Cow<'_, str>> {
29        Some(Cow::Borrowed(&self.code))
30    }
31
32    fn as_error(&self) -> &(dyn Error + Send + Sync + 'static) {
33        self
34    }
35
36    fn as_error_mut(&mut self) -> &mut (dyn Error + Send + Sync + 'static) {
37        self
38    }
39
40    fn into_error(self: Box<Self>) -> Box<dyn Error + Send + Sync + 'static> {
41        self
42    }
43
44    /// Uniqueness is only available to PRIMARY KEY columns in Exasol.
45    /// Additionally, there's no distinction between the PRIMARY and FOREIGN key
46    /// constraint violation codes, so we have to rely on the message as well.
47    ///
48    /// Furthermore, there's no CHECK constraint in Exasol.
49    fn kind(&self) -> ErrorKind {
50        match self.code.as_str() {
51            "27001" => ErrorKind::NotNullViolation,
52            "42X91" if self.text.contains("primary key") => ErrorKind::UniqueViolation,
53            "42X91" if self.text.contains("foreign key") => ErrorKind::ForeignKeyViolation,
54            _ => ErrorKind::Other,
55        }
56    }
57}