1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use thiserror::Error;
use std::io;
#[derive(Debug, Error)]
pub enum Error {
#[error("Error querying the database: {}", _0)]
QueryError(Box<dyn std::error::Error + Send + Sync + 'static>),
#[error("Database '{}' does not exist.", db_name)]
DatabaseDoesNotExist { db_name: String },
#[error("Access denied to database '{}'", db_name)]
DatabaseAccessDenied { db_name: String },
#[error("Database '{}' already exists", db_name)]
DatabaseAlreadyExists { db_name: String },
#[error("Authentication failed for user '{}'", user)]
AuthenticationFailed { user: String },
#[error("Query returned no data")]
NotFound,
#[error("Unique constraint failed: {}", field_name)]
UniqueConstraintViolation { field_name: String },
#[error("Null constraint failed: {}", field_name)]
NullConstraintViolation { field_name: String },
#[error("Error creating a database connection.")]
ConnectionError(Box<dyn std::error::Error + Send + Sync + 'static>),
#[error("Error reading the column value: {}", _0)]
ColumnReadFailure(Box<dyn std::error::Error + Send + Sync + 'static>),
#[error("Error accessing result set, index out of bounds: {}", _0)]
ResultIndexOutOfBounds(usize),
#[error("Error accessing result set, column not found: {}", _0)]
ColumnNotFound(String),
#[error("Error accessing result set, type mismatch, expected: {}", _0)]
ResultTypeMismatch(&'static str),
#[error("The specified database url {} is invalid", _0)]
DatabaseUrlIsInvalid(String),
#[error("Conversion failed: {}", _0)]
ConversionError(&'static str),
#[error("The provided arguments are not supported")]
InvalidConnectionArguments,
#[error("Error in an I/O operation")]
IoError(io::Error),
#[error("Connect timed out")]
ConnectTimeout,
#[error("Operation timed out")]
Timeout,
#[error("Error opening a TLS connection. {}", message)]
TlsError { message: String },
}
#[cfg(feature = "pooled")]
impl From<mobc::Error<Error>> for Error {
fn from(e: mobc::Error<Error>) -> Self {
match e {
mobc::Error::Inner(e) => e,
mobc::Error::Timeout => Self::Timeout,
e @ mobc::Error::BadConn => Self::ConnectionError(Box::new(e)),
}
}
}
#[cfg(any(feature = "postgresql", feature = "mysql"))]
impl From<tokio::time::Elapsed> for Error {
fn from(_: tokio::time::Elapsed) -> Self {
Self::Timeout
}
}
impl From<url::ParseError> for Error {
fn from(_: url::ParseError) -> Error {
Error::DatabaseUrlIsInvalid("Error parsing database connection string.".to_string())
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::IoError(e)
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(_: std::string::FromUtf8Error) -> Error {
Error::ConversionError("Couldn't convert data to UTF-8")
}
}