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>;