Simplify ConnectError

Same deal as Error
This commit is contained in:
Steven Fackler 2016-01-02 15:50:11 -08:00
parent ccfba62b99
commit 3ddcf87203
4 changed files with 29 additions and 33 deletions

View File

@ -174,19 +174,10 @@ impl error::Error for DbError {
/// Reasons a new Postgres connection could fail. /// Reasons a new Postgres connection could fail.
#[derive(Debug)] #[derive(Debug)]
pub enum ConnectError { pub enum ConnectError {
/// An error creating `ConnectParams`. /// An error relating to connection parameters.
BadConnectParams(Box<error::Error + Sync + Send>), ConnectParams(Box<error::Error + Sync + Send>),
/// The `ConnectParams` was missing a user.
MissingUser,
/// An error from the Postgres server itself. /// An error from the Postgres server itself.
Db(Box<DbError>), Db(Box<DbError>),
/// A password was required but not provided in the `ConnectParams`.
MissingPassword,
/// The Postgres server requested an authentication method not supported
/// by the driver.
UnsupportedAuthentication,
/// The Postgres server does not support SSL encryption.
NoSslSupport,
/// An error initializing the SSL session. /// An error initializing the SSL session.
Ssl(Box<error::Error + Sync + Send>), Ssl(Box<error::Error + Sync + Send>),
/// An error communicating with the server. /// An error communicating with the server.
@ -197,11 +188,10 @@ impl fmt::Display for ConnectError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(fmt.write_str(error::Error::description(self))); try!(fmt.write_str(error::Error::description(self)));
match *self { match *self {
ConnectError::BadConnectParams(ref msg) => write!(fmt, ": {}", msg), ConnectError::ConnectParams(ref msg) => write!(fmt, ": {}", msg),
ConnectError::Db(ref err) => write!(fmt, ": {}", err), ConnectError::Db(ref err) => write!(fmt, ": {}", err),
ConnectError::Ssl(ref err) => write!(fmt, ": {}", err), ConnectError::Ssl(ref err) => write!(fmt, ": {}", err),
ConnectError::Io(ref err) => write!(fmt, ": {}", err), ConnectError::Io(ref err) => write!(fmt, ": {}", err),
_ => Ok(()),
} }
} }
} }
@ -209,16 +199,8 @@ impl fmt::Display for ConnectError {
impl error::Error for ConnectError { impl error::Error for ConnectError {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
ConnectError::BadConnectParams(_) => "Error creating `ConnectParams`", ConnectError::ConnectParams(_) => "Invalid connection parameters",
ConnectError::MissingUser => "User missing in `ConnectParams`",
ConnectError::Db(_) => "Error reported by Postgres", ConnectError::Db(_) => "Error reported by Postgres",
ConnectError::MissingPassword => {
"The server requested a password but none was provided"
}
ConnectError::UnsupportedAuthentication => {
"The server requested an unsupported authentication method"
}
ConnectError::NoSslSupport => "The server does not support SSL",
ConnectError::Ssl(_) => "Error initiating SSL session", ConnectError::Ssl(_) => "Error initiating SSL session",
ConnectError::Io(_) => "Error communicating with the server", ConnectError::Io(_) => "Error communicating with the server",
} }
@ -226,11 +208,10 @@ impl error::Error for ConnectError {
fn cause(&self) -> Option<&error::Error> { fn cause(&self) -> Option<&error::Error> {
match *self { match *self {
ConnectError::BadConnectParams(ref err) => Some(&**err), ConnectError::ConnectParams(ref err) => Some(&**err),
ConnectError::Db(ref err) => Some(&**err), ConnectError::Db(ref err) => Some(&**err),
ConnectError::Ssl(ref err) => Some(&**err), ConnectError::Ssl(ref err) => Some(&**err),
ConnectError::Io(ref err) => Some(err), ConnectError::Io(ref err) => Some(err),
_ => None,
} }
} }
} }

View File

@ -272,7 +272,7 @@ pub fn cancel_query<T>(params: T,
-> result::Result<(), ConnectError> -> result::Result<(), ConnectError>
where T: IntoConnectParams where T: IntoConnectParams
{ {
let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams)); let params = try!(params.into_connect_params().map_err(ConnectError::ConnectParams));
let mut socket = try!(priv_io::initialize_stream(&params, ssl)); let mut socket = try!(priv_io::initialize_stream(&params, ssl));
try!(socket.write_message(&CancelRequest { try!(socket.write_message(&CancelRequest {
@ -394,12 +394,18 @@ impl InnerConnection {
fn connect<T>(params: T, ssl: SslMode) -> result::Result<InnerConnection, ConnectError> fn connect<T>(params: T, ssl: SslMode) -> result::Result<InnerConnection, ConnectError>
where T: IntoConnectParams where T: IntoConnectParams
{ {
let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams)); let params = try!(params.into_connect_params().map_err(ConnectError::ConnectParams));
let stream = try!(priv_io::initialize_stream(&params, ssl)); let stream = try!(priv_io::initialize_stream(&params, ssl));
let ConnectParams { user, database, mut options, .. } = params; let ConnectParams { user, database, mut options, .. } = params;
let user = try!(user.ok_or(ConnectError::MissingUser)); let user = match user {
Some(user) => user,
None => {
let err: Box<StdError + StdSync + Send> = "User missing from connection parameters".into();
return Err(ConnectError::ConnectParams(err));
}
};
let mut conn = InnerConnection { let mut conn = InnerConnection {
stream: BufStream::new(stream), stream: BufStream::new(stream),
@ -564,11 +570,15 @@ impl InnerConnection {
match try!(self.read_message()) { match try!(self.read_message()) {
AuthenticationOk => return Ok(()), AuthenticationOk => return Ok(()),
AuthenticationCleartextPassword => { AuthenticationCleartextPassword => {
let pass = try!(user.password.ok_or(ConnectError::MissingPassword)); let pass = try!(user.password.ok_or_else(|| {
ConnectError::ConnectParams("a password was requested but not provided".into())
}));
try!(self.write_messages(&[PasswordMessage { password: &pass }])); try!(self.write_messages(&[PasswordMessage { password: &pass }]));
} }
AuthenticationMD5Password { salt } => { AuthenticationMD5Password { salt } => {
let pass = try!(user.password.ok_or(ConnectError::MissingPassword)); let pass = try!(user.password.ok_or_else(|| {
ConnectError::ConnectParams("a password was requested but not provided".into())
}));
let mut hasher = Md5::new(); let mut hasher = Md5::new();
hasher.input(pass.as_bytes()); hasher.input(pass.as_bytes());
hasher.input(user.user.as_bytes()); hasher.input(user.user.as_bytes());
@ -582,7 +592,10 @@ impl InnerConnection {
AuthenticationKerberosV5 | AuthenticationKerberosV5 |
AuthenticationSCMCredential | AuthenticationSCMCredential |
AuthenticationGSS | AuthenticationGSS |
AuthenticationSSPI => return Err(ConnectError::UnsupportedAuthentication), AuthenticationSSPI => {
return Err(ConnectError::Io(std_io::Error::new(std_io::ErrorKind::Other,
"unsupported authentication")))
}
ErrorResponse { fields } => return DbError::new_connect(fields), ErrorResponse { fields } => return DbError::new_connect(fields),
_ => return Err(ConnectError::Io(bad_response())), _ => return Err(ConnectError::Io(bad_response())),
} }

View File

@ -1,5 +1,6 @@
use byteorder::ReadBytesExt; use byteorder::ReadBytesExt;
use net2::TcpStreamExt; use net2::TcpStreamExt;
use std::error::Error;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::fmt; use std::fmt;
@ -172,7 +173,8 @@ pub fn initialize_stream(params: &ConnectParams,
if try!(socket.read_u8()) == b'N' { if try!(socket.read_u8()) == b'N' {
if ssl_required { if ssl_required {
return Err(ConnectError::NoSslSupport); let err: Box<Error + Sync + Send> = "The server does not support SSL".into();
return Err(ConnectError::Ssl(err));
} else { } else {
return Ok(Box::new(socket)); return Ok(Box::new(socket));
} }

View File

@ -698,7 +698,7 @@ fn test_plaintext_pass() {
fn test_plaintext_pass_no_pass() { fn test_plaintext_pass_no_pass() {
let ret = Connection::connect("postgres://pass_user@localhost/postgres", SslMode::None); let ret = Connection::connect("postgres://pass_user@localhost/postgres", SslMode::None);
match ret { match ret {
Err(ConnectError::MissingPassword) => (), Err(ConnectError::ConnectParams(..)) => (),
Err(err) => panic!("Unexpected error {:?}", err), Err(err) => panic!("Unexpected error {:?}", err),
_ => panic!("Expected error") _ => panic!("Expected error")
} }
@ -723,7 +723,7 @@ fn test_md5_pass() {
fn test_md5_pass_no_pass() { fn test_md5_pass_no_pass() {
let ret = Connection::connect("postgres://md5_user@localhost/postgres", SslMode::None); let ret = Connection::connect("postgres://md5_user@localhost/postgres", SslMode::None);
match ret { match ret {
Err(ConnectError::MissingPassword) => (), Err(ConnectError::ConnectParams(..)) => (),
Err(err) => panic!("Unexpected error {:?}", err), Err(err) => panic!("Unexpected error {:?}", err),
_ => panic!("Expected error") _ => panic!("Expected error")
} }