Remove failure from PostgresDbError::new

Closes #43
This commit is contained in:
Steven Fackler 2014-09-30 22:52:27 -07:00
parent 5561e7baca
commit a64ca5f955
2 changed files with 54 additions and 37 deletions

View File

@ -1,13 +1,13 @@
//! Postgres errors //! Postgres errors
use std::collections::HashMap; use std::collections::HashMap;
use std::from_str::FromStr;
use std::io; use std::io;
use std::fmt; use std::fmt;
use openssl::ssl::error; use openssl::ssl::error;
use phf::PhfMap; use phf::PhfMap;
use PostgresResult;
use types::PostgresType; use types::PostgresType;
macro_rules! make_errors( macro_rules! make_errors(
@ -480,33 +480,49 @@ pub struct PostgresDbError {
impl PostgresDbError { impl PostgresDbError {
#[doc(hidden)] #[doc(hidden)]
pub fn new(fields: Vec<(u8, String)>) -> PostgresDbError { pub fn new_raw(fields: Vec<(u8, String)>) -> Result<PostgresDbError, ()> {
let mut map: HashMap<_, _> = fields.into_iter().collect(); let mut map: HashMap<_, _> = fields.into_iter().collect();
PostgresDbError { Ok(PostgresDbError {
severity: map.pop(&('S' as u8)).unwrap(), severity: try!(map.pop(&b'S').ok_or(())),
code: PostgresSqlState::from_code(map.pop(&('C' as u8)).unwrap().as_slice()), code: PostgresSqlState::from_code(try!(map.pop(&b'C').ok_or(())).as_slice()),
message: map.pop(&('M' as u8)).unwrap(), message: try!(map.pop(&b'M').ok_or(())),
detail: map.pop(&('D' as u8)), detail: map.pop(&b'D'),
hint: map.pop(&('H' as u8)), hint: map.pop(&b'H'),
position: match map.pop(&('P' as u8)) { position: match map.pop(&b'P') {
Some(pos) => Some(Position(FromStr::from_str(pos.as_slice()).unwrap())), Some(pos) => Some(Position(try!(from_str(pos.as_slice()).ok_or(())))),
None => match map.pop(&('p' as u8)) { None => match map.pop(&b'p') {
Some(pos) => Some(InternalPosition { Some(pos) => Some(InternalPosition {
position: FromStr::from_str(pos.as_slice()).unwrap(), position: try!(from_str(pos.as_slice()).ok_or(())),
query: map.pop(&('q' as u8)).unwrap() query: try!(map.pop(&b'q').ok_or(()))
}), }),
None => None None => None
} }
}, },
where_: map.pop(&('W' as u8)), where_: map.pop(&b'W'),
schema: map.pop(&('s' as u8)), schema: map.pop(&b's'),
table: map.pop(&('t' as u8)), table: map.pop(&b't'),
column: map.pop(&('c' as u8)), column: map.pop(&b'c'),
datatype: map.pop(&('d' as u8)), datatype: map.pop(&b'd'),
constraint: map.pop(&('n' as u8)), constraint: map.pop(&b'n'),
file: map.pop(&('F' as u8)).unwrap(), file: try!(map.pop(&b'F').ok_or(())),
line: FromStr::from_str(map.pop(&('L' as u8)).unwrap().as_slice()).unwrap(), line: try!(map.pop(&b'L').and_then(|l| from_str(l.as_slice())).ok_or(())),
routine: map.pop(&('R' as u8)).unwrap() routine: map.pop(&b'R').unwrap()
})
}
#[doc(hidden)]
pub fn new_connect<T>(fields: Vec<(u8, String)>) -> Result<T, PostgresConnectError> {
match PostgresDbError::new_raw(fields) {
Ok(err) => Err(PgConnectDbError(err)),
Err(()) => Err(PgConnectBadResponse),
}
}
#[doc(hidden)]
pub fn new<T>(fields: Vec<(u8, String)>) -> PostgresResult<T> {
match PostgresDbError::new_raw(fields) {
Ok(err) => Err(PgDbError(err)),
Err(()) => Err(PgBadData),
} }
} }
} }

View File

@ -80,10 +80,8 @@ use std::fmt;
use error::{InvalidUrl, use error::{InvalidUrl,
MissingPassword, MissingPassword,
MissingUser, MissingUser,
PgConnectDbError,
PgConnectStreamError, PgConnectStreamError,
PgConnectBadResponse, PgConnectBadResponse,
PgDbError,
PgInvalidColumn, PgInvalidColumn,
PgStreamDesynchronized, PgStreamDesynchronized,
PgStreamError, PgStreamError,
@ -428,7 +426,7 @@ impl InnerPostgresConnection {
} }
ReadyForQuery { .. } => break, ReadyForQuery { .. } => break,
ErrorResponse { fields } => ErrorResponse { fields } =>
return Err(PgConnectDbError(PostgresDbError::new(fields))), return PostgresDbError::new_connect(fields),
_ => return Err(PgConnectBadResponse), _ => return Err(PgConnectBadResponse),
} }
} }
@ -449,7 +447,10 @@ impl InnerPostgresConnection {
loop { loop {
match try_desync!(self, self.stream.read_message()) { match try_desync!(self, self.stream.read_message()) {
NoticeResponse { fields } => { NoticeResponse { fields } => {
self.notice_handler.handle(PostgresDbError::new(fields)) match PostgresDbError::new_raw(fields) {
Ok(err) => self.notice_handler.handle(err),
Err(()) => {}
}
} }
NotificationResponse { pid, channel, payload } => { NotificationResponse { pid, channel, payload } => {
self.notifications.push(PostgresNotification { self.notifications.push(PostgresNotification {
@ -500,7 +501,7 @@ impl InnerPostgresConnection {
| AuthenticationSCMCredential | AuthenticationSCMCredential
| AuthenticationGSS | AuthenticationGSS
| AuthenticationSSPI => return Err(UnsupportedAuthentication), | AuthenticationSSPI => return Err(UnsupportedAuthentication),
ErrorResponse { fields } => return Err(PgConnectDbError(PostgresDbError::new(fields))), ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
_ => { _ => {
self.desynchronized = true; self.desynchronized = true;
return Err(PgConnectBadResponse); return Err(PgConnectBadResponse);
@ -509,7 +510,7 @@ impl InnerPostgresConnection {
match try_pg_conn!(self.read_message_()) { match try_pg_conn!(self.read_message_()) {
AuthenticationOk => Ok(()), AuthenticationOk => Ok(()),
ErrorResponse { fields } => Err(PgConnectDbError(PostgresDbError::new(fields))), ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
_ => { _ => {
self.desynchronized = true; self.desynchronized = true;
return Err(PgConnectBadResponse); return Err(PgConnectBadResponse);
@ -543,7 +544,7 @@ impl InnerPostgresConnection {
ParseComplete => {} ParseComplete => {}
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(self.wait_for_ready()); try!(self.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => bad_response!(self), _ => bad_response!(self),
} }
@ -629,7 +630,7 @@ impl InnerPostgresConnection {
ReadyForQuery { .. } => break, ReadyForQuery { .. } => break,
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(self.wait_for_ready()); try!(self.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => {} _ => {}
} }
@ -691,7 +692,7 @@ impl InnerPostgresConnection {
} }
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(self.wait_for_ready()); try!(self.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => {} _ => {}
} }
@ -1184,7 +1185,7 @@ impl<'conn> PostgresStatement<'conn> {
BindComplete => Ok(()), BindComplete => Ok(()),
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
Err(PgDbError(PostgresDbError::new(fields))) PostgresDbError::new(fields)
} }
_ => { _ => {
conn.desynchronized = true; conn.desynchronized = true;
@ -1251,7 +1252,7 @@ impl<'conn> PostgresStatement<'conn> {
DataRow { .. } => {} DataRow { .. } => {}
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
CommandComplete { tag } => { CommandComplete { tag } => {
num = util::parse_update_count(tag); num = util::parse_update_count(tag);
@ -1357,7 +1358,7 @@ impl<'stmt> PostgresRows<'stmt> {
ReadyForQuery { .. } => break, ReadyForQuery { .. } => break,
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => {} _ => {}
} }
@ -1381,7 +1382,7 @@ impl<'stmt> PostgresRows<'stmt> {
DataRow { row } => self.data.push(row), DataRow { row } => self.data.push(row),
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
CopyInResponse { .. } => { CopyInResponse { .. } => {
try_pg!(conn.write_messages([ try_pg!(conn.write_messages([
@ -1622,7 +1623,7 @@ impl<'a> PostgresCopyInStatement<'a> {
BindComplete => {}, BindComplete => {},
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => { _ => {
conn.desynchronized = true; conn.desynchronized = true;
@ -1692,7 +1693,7 @@ impl<'a> PostgresCopyInStatement<'a> {
CommandComplete { tag } => util::parse_update_count(tag), CommandComplete { tag } => util::parse_update_count(tag),
ErrorResponse { fields } => { ErrorResponse { fields } => {
try!(conn.wait_for_ready()); try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields))); return PostgresDbError::new(fields);
} }
_ => { _ => {
conn.desynchronized = true; conn.desynchronized = true;