Generify connect params errors

This commit is contained in:
Steven Fackler 2015-06-15 22:20:09 -07:00
parent ca37366db6
commit de8c882ef0
2 changed files with 20 additions and 17 deletions

View File

@ -193,8 +193,8 @@ impl error::Error for DbError {
/// Reasons a new Postgres connection could fail.
#[derive(Debug)]
pub enum ConnectError {
/// The provided URL could not be parsed.
InvalidUrl(String),
/// An error creating `ConnectParams`.
BadConnectParams(Box<error::Error+Sync+Send>),
/// The URL was missing a user.
MissingUser,
/// An error from the Postgres server itself.
@ -216,7 +216,7 @@ impl fmt::Display for ConnectError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(fmt.write_str(error::Error::description(self)));
match *self {
ConnectError::InvalidUrl(ref msg) => write!(fmt, ": {}", msg),
ConnectError::BadConnectParams(ref msg) => write!(fmt, ": {}", msg),
ConnectError::DbError(ref err) => write!(fmt, ": {}", err),
ConnectError::SslError(ref err) => write!(fmt, ": {}", err),
ConnectError::IoError(ref err) => write!(fmt, ": {}", err),
@ -228,8 +228,8 @@ impl fmt::Display for ConnectError {
impl error::Error for ConnectError {
fn description(&self) -> &str {
match *self {
ConnectError::InvalidUrl(_) => "Invalid URL",
ConnectError::MissingUser => "User missing in URL",
ConnectError::BadConnectParams(_) => "Error creating `ConnectParams`",
ConnectError::MissingUser => "User missing in `ConnectParams`",
ConnectError::DbError(_) => "Error reported by Postgres",
ConnectError::MissingPassword => "The server requested a password but none was provided",
ConnectError::UnsupportedAuthentication => {
@ -243,6 +243,7 @@ impl error::Error for ConnectError {
fn cause(&self) -> Option<&error::Error> {
match *self {
ConnectError::BadConnectParams(ref err) => Some(&**err),
ConnectError::DbError(ref err) => Some(err),
ConnectError::SslError(ref err) => Some(&**err),
ConnectError::IoError(ref err) => Some(err),

View File

@ -61,10 +61,12 @@ use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::{Cell, RefCell};
use std::collections::{VecDeque, HashMap};
use std::error::Error as StdError;
use std::fmt;
use std::iter::IntoIterator;
use std::io as std_io;
use std::io::prelude::*;
use std::marker::Sync as StdSync;
use std::mem;
use std::result;
#[cfg(feature = "unix_socket")]
@ -145,26 +147,26 @@ pub struct ConnectParams {
/// A trait implemented by types that can be converted into a `ConnectParams`.
pub trait IntoConnectParams {
/// Converts the value of `self` into a `ConnectParams`.
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError>;
fn into_connect_params(self) -> result::Result<ConnectParams, Box<StdError+StdSync+Send>>;
}
impl IntoConnectParams for ConnectParams {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, Box<StdError+StdSync+Send>> {
Ok(self)
}
}
impl<'a> IntoConnectParams for &'a str {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, Box<StdError+StdSync+Send>> {
match Url::parse(self) {
Ok(url) => url.into_connect_params(),
Err(err) => return Err(ConnectError::InvalidUrl(err)),
Err(err) => return Err(err.into()),
}
}
}
impl IntoConnectParams for Url {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, Box<StdError+StdSync+Send>> {
let Url {
host,
port,
@ -174,16 +176,16 @@ impl IntoConnectParams for Url {
} = self;
#[cfg(feature = "unix_socket")]
fn make_unix(maybe_path: String) -> result::Result<ConnectTarget, ConnectError> {
fn make_unix(maybe_path: String)
-> result::Result<ConnectTarget, Box<StdError+StdSync+Send>> {
Ok(ConnectTarget::Unix(PathBuf::from(maybe_path)))
}
#[cfg(not(feature = "unix_socket"))]
fn make_unix(_: String) -> result::Result<ConnectTarget, ConnectError> {
Err(ConnectError::InvalidUrl("unix socket support requires the `unix_socket` feature"
.to_string()))
fn make_unix(_: String) -> result::Result<ConnectTarget, Box<StdError+StdSync+Send>> {
Err("unix socket support requires the `unix_socket` feature".into())
}
let maybe_path = try!(url::decode_component(&host).map_err(ConnectError::InvalidUrl));
let maybe_path = try!(url::decode_component(&host));
let target = if maybe_path.starts_with("/") {
try!(make_unix(maybe_path))
} else {
@ -330,7 +332,7 @@ pub struct CancelData {
pub fn cancel_query<T>(params: T, ssl: &SslMode, data: CancelData)
-> result::Result<(), ConnectError>
where T: IntoConnectParams {
let params = try!(params.into_connect_params());
let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams));
let mut socket = try!(priv_io::initialize_stream(&params, ssl));
try!(socket.write_message(&CancelRequest {
@ -459,7 +461,7 @@ impl Drop for InnerConnection {
impl InnerConnection {
fn connect<T>(params: T, ssl: &SslMode) -> result::Result<InnerConnection, ConnectError>
where T: IntoConnectParams {
let params = try!(params.into_connect_params());
let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams));
let stream = try!(priv_io::initialize_stream(&params, ssl));
let ConnectParams { user, database, mut options, .. } = params;