Skip to content

Commit 15a1b79

Browse files
committed
Unify error types for postgres
1 parent 7069c57 commit 15a1b79

File tree

10 files changed

+268
-226
lines changed

10 files changed

+268
-226
lines changed

postgres/src/error.rs

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,106 @@ use std::error;
77
// FIXME
88
pub use postgres_shared::error::*;
99

10-
/// An error encountered when communicating with the Postgres server.
1110
#[derive(Debug)]
12-
pub enum Error {
13-
/// An error reported by the Postgres server.
14-
Db(Box<DbError>),
15-
/// An error communicating with the Postgres server.
11+
pub(crate) enum ErrorKind {
12+
ConnectParams(Box<error::Error + Sync + Send>),
13+
Tls(Box<error::Error + Sync + Send>),
14+
Db(DbError),
1615
Io(io::Error),
17-
/// An error converting between Postgres and Rust types.
1816
Conversion(Box<error::Error + Sync + Send>),
1917
}
2018

19+
/// An error communicating with the Postgres server.
20+
#[derive(Debug)]
21+
pub struct Error(pub(crate) Box<ErrorKind>);
22+
2123
impl fmt::Display for Error {
2224
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
2325
fmt.write_str(error::Error::description(self))?;
24-
match *self {
25-
Error::Db(ref err) => write!(fmt, ": {}", err),
26-
Error::Io(ref err) => write!(fmt, ": {}", err),
27-
Error::Conversion(ref err) => write!(fmt, ": {}", err),
26+
match *self.0 {
27+
ErrorKind::ConnectParams(ref err) => write!(fmt, ": {}", err),
28+
ErrorKind::Tls(ref err) => write!(fmt, ": {}", err),
29+
ErrorKind::Db(ref err) => write!(fmt, ": {}", err),
30+
ErrorKind::Io(ref err) => write!(fmt, ": {}", err),
31+
ErrorKind::Conversion(ref err) => write!(fmt, ": {}", err),
2832
}
2933
}
3034
}
3135

3236
impl error::Error for Error {
3337
fn description(&self) -> &str {
34-
match *self {
35-
Error::Db(_) => "Error reported by Postgres",
36-
Error::Io(_) => "Error communicating with the server",
37-
Error::Conversion(_) => "Error converting between Postgres and Rust types",
38+
match *self.0 {
39+
ErrorKind::ConnectParams(_) => "invalid connection parameters",
40+
ErrorKind::Tls(_) => "TLS handshake error",
41+
ErrorKind::Db(_) => "database error",
42+
ErrorKind::Io(_) => "IO error",
43+
ErrorKind::Conversion(_) => "type conversion error",
3844
}
3945
}
4046

4147
fn cause(&self) -> Option<&error::Error> {
42-
match *self {
43-
Error::Db(ref err) => Some(&**err),
44-
Error::Io(ref err) => Some(err),
45-
Error::Conversion(ref err) => Some(&**err),
48+
match *self.0 {
49+
ErrorKind::ConnectParams(ref err) => Some(&**err),
50+
ErrorKind::Tls(ref err) => Some(&**err),
51+
ErrorKind::Db(ref err) => Some(err),
52+
ErrorKind::Io(ref err) => Some(err),
53+
ErrorKind::Conversion(ref err) => Some(&**err),
4654
}
4755
}
4856
}
4957

50-
impl From<DbError> for Error {
51-
fn from(err: DbError) -> Error {
52-
Error::Db(Box::new(err))
58+
impl Error {
59+
/// Returns the SQLSTATE error code associated with this error if it is a DB
60+
/// error.
61+
pub fn code(&self) -> Option<&SqlState> {
62+
self.as_db().map(|e| &e.code)
63+
}
64+
65+
/// Returns the inner error if this is a connection parameter error.
66+
pub fn as_connection(&self) -> Option<&(error::Error + 'static + Sync + Send)> {
67+
match *self.0 {
68+
ErrorKind::ConnectParams(ref err) => Some(&**err),
69+
_ => None,
70+
}
71+
}
72+
73+
/// Returns the `DbError` associated with this error if it is a DB error.
74+
pub fn as_db(&self) -> Option<&DbError> {
75+
match *self.0 {
76+
ErrorKind::Db(ref err) => Some(err),
77+
_ => None
78+
}
79+
}
80+
81+
/// Returns the inner error if this is a conversion error.
82+
pub fn as_conversion(&self) -> Option<&(error::Error + 'static + Sync + Send)> {
83+
match *self.0 {
84+
ErrorKind::Conversion(ref err) => Some(&**err),
85+
_ => None,
86+
}
87+
}
88+
89+
/// Returns the inner `io::Error` associated with this error if it is an IO
90+
/// error.
91+
pub fn as_io(&self) -> Option<&io::Error> {
92+
match *self.0 {
93+
ErrorKind::Io(ref err) => Some(err),
94+
_ => None,
95+
}
5396
}
5497
}
5598

5699
impl From<io::Error> for Error {
57100
fn from(err: io::Error) -> Error {
58-
Error::Io(err)
101+
Error(Box::new(ErrorKind::Io(err)))
59102
}
60103
}
61104

62105
impl From<Error> for io::Error {
63106
fn from(err: Error) -> io::Error {
64-
io::Error::new(io::ErrorKind::Other, err)
107+
match *err.0 {
108+
ErrorKind::Io(e) => e,
109+
_ => io::Error::new(io::ErrorKind::Other, err),
110+
}
65111
}
66112
}

0 commit comments

Comments
 (0)