Skip to main content

pgwire_replication/
error.rs

1//! Error types for pgwire-replication.
2//!
3//! All errors in this crate are represented by [`PgWireError`], which covers:
4//! - I/O errors (network, file system)
5//! - Protocol errors (malformed messages, unexpected responses)
6//! - Server errors (PostgreSQL error responses)
7//! - Authentication errors (wrong password, unsupported method)
8//! - TLS errors (handshake failure, certificate issues)
9//! - Task errors (worker panics, unexpected termination)
10
11use std::sync::Arc;
12use thiserror::Error;
13
14/// Error type for all pgwire-replication operations.
15#[derive(Debug, Error, Clone)]
16pub enum PgWireError {
17    /// I/O error (network, file system).
18    ///
19    /// Wraps `std::io::Error` in an `Arc` to preserve `ErrorKind` while
20    /// keeping `PgWireError` `Clone`. Use `.kind()` via `Arc`'s `Deref`.
21    #[error("io error: {0}")]
22    Io(Arc<std::io::Error>),
23
24    /// Protocol error - malformed message or unexpected response.
25    #[error("protocol error: {0}")]
26    Protocol(String),
27
28    /// Server error - PostgreSQL returned an error response.
29    ///
30    /// The message typically includes SQLSTATE code.
31    #[error("server error: {0}")]
32    Server(String),
33
34    /// Authentication error - wrong credentials or unsupported method.
35    #[error("authentication error: {0}")]
36    Auth(String),
37
38    /// TLS error - handshake failure, certificate validation, etc.
39    #[error("tls error: {0}")]
40    Tls(String),
41
42    /// Task error - worker panicked or terminated unexpectedly.
43    #[error("task error: {0}")]
44    Task(String),
45
46    /// Internal error - bug in the library.
47    #[error("internal error: {0}")]
48    Internal(String),
49}
50
51impl PgWireError {
52    /// Returns `true` if this is an I/O error.
53    #[inline]
54    pub fn is_io(&self) -> bool {
55        matches!(self, PgWireError::Io(_))
56    }
57
58    /// Returns `true` if this is a server error.
59    #[inline]
60    pub fn is_server(&self) -> bool {
61        matches!(self, PgWireError::Server(_))
62    }
63
64    /// Returns `true` if this is an authentication error.
65    #[inline]
66    pub fn is_auth(&self) -> bool {
67        matches!(self, PgWireError::Auth(_))
68    }
69
70    /// Returns `true` if this is a TLS error.
71    #[inline]
72    pub fn is_tls(&self) -> bool {
73        matches!(self, PgWireError::Tls(_))
74    }
75
76    /// Returns `true` if this error is likely transient and retryable.
77    ///
78    /// Transient errors include I/O errors and task errors. Non-transient
79    /// errors (auth, server, protocol) typically require configuration changes.
80    pub fn is_transient(&self) -> bool {
81        matches!(self, PgWireError::Io(_) | PgWireError::Task(_))
82    }
83}
84
85impl From<std::io::Error> for PgWireError {
86    fn from(err: std::io::Error) -> Self {
87        PgWireError::Io(Arc::new(err))
88    }
89}
90
91/// Result type alias for pgwire-replication operations.
92pub type Result<T> = std::result::Result<T, PgWireError>;