persistant_relational/error.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2use std::fmt;
3
4/// Why a relational operation failed, classified so a caller can branch without parsing driver
5/// text (Humboldt hand-maps constraint names in at least seven places today). Plain data.
6#[derive(Debug, Clone, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum RelError {
9 /// A unique or primary-key constraint rejected the statement.
10 UniqueViolation {
11 /// The constraint's name, if the server reports it.
12 constraint: Option<String>,
13 },
14 /// A foreign-key constraint rejected the statement.
15 ForeignKeyViolation {
16 /// The constraint's name, if the server reports it.
17 constraint: Option<String>,
18 },
19 /// A check constraint (or NOT NULL) rejected the statement.
20 CheckViolation {
21 /// The constraint's name, if the server reports it.
22 constraint: Option<String>,
23 },
24 /// The transaction could not be serialised; retrying it may succeed.
25 Serialization,
26 /// The server chose this transaction as a deadlock victim; retrying it may succeed.
27 Deadlock,
28 /// The server could not be reached or went away.
29 Unavailable(String),
30 /// The backend cannot do this, and says so rather than approximating.
31 Unsupported(String),
32 /// A call did not finish within the configured per-call bound and was cut off. For a statement
33 /// outside a transaction, whether it took effect is unknown; a transaction that saw one is
34 /// rolled back and refuses to commit.
35 Timeout {
36 /// The bound that expired.
37 after: std::time::Duration,
38 },
39 /// Any other failure; the text is the driver's.
40 Backend(String),
41}
42
43impl fmt::Display for RelError {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 let c = |c: &Option<String>| c.as_deref().unwrap_or("?").to_string();
46 match self {
47 RelError::UniqueViolation { constraint } => {
48 write!(f, "unique violation ({})", c(constraint))
49 }
50 RelError::ForeignKeyViolation { constraint } => {
51 write!(f, "foreign key violation ({})", c(constraint))
52 }
53 RelError::CheckViolation { constraint } => {
54 write!(f, "check violation ({})", c(constraint))
55 }
56 RelError::Serialization => f.write_str("serialization failure"),
57 RelError::Deadlock => f.write_str("deadlock detected"),
58 RelError::Unavailable(m) => write!(f, "database unavailable: {m}"),
59 RelError::Unsupported(m) => write!(f, "database does not support: {m}"),
60 RelError::Timeout { after } => write!(f, "database call timed out after {after:?}"),
61 RelError::Backend(m) => write!(f, "database: {m}"),
62 }
63 }
64}
65
66impl std::error::Error for RelError {}