1use std::fmt;
2
3pub type Result<T> = std::result::Result<T, PgError>;
4
5#[derive(Debug)]
6pub struct DbError {
7 pub severity: String,
8 pub code: String,
9 pub message: String,
10 pub detail: Option<String>,
11 pub hint: Option<String>,
12 pub position: Option<i32>,
13}
14
15impl fmt::Display for DbError {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 write!(f, "{}: {} (code: {})", self.severity, self.message, self.code)?;
18 if let Some(detail) = &self.detail {
19 write!(f, "\n detail: {}", detail)?;
20 }
21 if let Some(hint) = &self.hint {
22 write!(f, "\n hint: {}", hint)?;
23 }
24 Ok(())
25 }
26}
27
28impl std::error::Error for DbError {}
29
30#[derive(Debug, thiserror::Error)]
31pub enum PgError {
32 #[error("IO error: {0}")]
33 Io(#[from] std::io::Error),
34
35 #[error("TLS error: {0}")]
36 Tls(Box<dyn std::error::Error + Send + Sync>),
37
38 #[error("Protocol error: {0}")]
39 Protocol(String),
40
41 #[error("Server error: {0}")]
42 Server(#[from] DbError),
43
44 #[error("Auth error: {0}")]
45 Auth(String),
46
47 #[error("Pool closed")]
48 PoolClosed,
49
50 #[error("Pool timeout")]
51 PoolTimeout,
52
53 #[error("Config error: {0}")]
54 Config(String),
55
56 #[error("Decode error: {0}")]
57 Decode(String),
58
59 #[error("Encode error: {0}")]
60 Encode(String),
61
62 #[error("Row not found")]
63 RowNotFound,
64
65 #[error("Column not found: {0}")]
66 ColumnNotFound(String),
67}
68
69impl From<rustls::Error> for PgError {
70 fn from(e: rustls::Error) -> Self {
71 PgError::Tls(Box::new(e))
72 }
73}
74
75impl From<Box<dyn std::error::Error + Send + Sync>> for PgError {
76 fn from(e: Box<dyn std::error::Error + Send + Sync>) -> Self {
77 PgError::Tls(e)
78 }
79}