Skip to main content

pg/
error.rs

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}