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
// SPDX-License-Identifier: MIT OR Apache-2.0
use std::fmt;
/// Why a relational operation failed, classified so a caller can branch without parsing driver
/// text (Humboldt hand-maps constraint names in at least seven places today). Plain data.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum RelError {
/// A unique or primary-key constraint rejected the statement.
UniqueViolation {
/// The constraint's name, if the server reports it.
constraint: Option<String>,
},
/// A foreign-key constraint rejected the statement.
ForeignKeyViolation {
/// The constraint's name, if the server reports it.
constraint: Option<String>,
},
/// A check constraint (or NOT NULL) rejected the statement.
CheckViolation {
/// The constraint's name, if the server reports it.
constraint: Option<String>,
},
/// The transaction could not be serialised; retrying it may succeed.
Serialization,
/// The server chose this transaction as a deadlock victim; retrying it may succeed.
Deadlock,
/// The server could not be reached or went away.
Unavailable(String),
/// The backend cannot do this, and says so rather than approximating.
Unsupported(String),
/// A call did not finish within the configured per-call bound and was cut off. For a statement
/// outside a transaction, whether it took effect is unknown; a transaction that saw one is
/// rolled back and refuses to commit.
Timeout {
/// The bound that expired.
after: std::time::Duration,
},
/// Any other failure; the text is the driver's.
Backend(String),
}
impl fmt::Display for RelError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c = |c: &Option<String>| c.as_deref().unwrap_or("?").to_string();
match self {
RelError::UniqueViolation { constraint } => {
write!(f, "unique violation ({})", c(constraint))
}
RelError::ForeignKeyViolation { constraint } => {
write!(f, "foreign key violation ({})", c(constraint))
}
RelError::CheckViolation { constraint } => {
write!(f, "check violation ({})", c(constraint))
}
RelError::Serialization => f.write_str("serialization failure"),
RelError::Deadlock => f.write_str("deadlock detected"),
RelError::Unavailable(m) => write!(f, "database unavailable: {m}"),
RelError::Unsupported(m) => write!(f, "database does not support: {m}"),
RelError::Timeout { after } => write!(f, "database call timed out after {after:?}"),
RelError::Backend(m) => write!(f, "database: {m}"),
}
}
}
impl std::error::Error for RelError {}