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
use std::collections::HashMap;
use std::from_str::FromStr;
use std::io;
use std::fmt;
use openssl::ssl::error;
use phf::PhfMap;
use PostgresResult;
use types::PostgresType;
macro_rules! make_errors(
@ -480,33 +480,49 @@ pub struct PostgresDbError {
impl PostgresDbError {
#[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();
PostgresDbError {
severity: map.pop(&('S' as u8)).unwrap(),
code: PostgresSqlState::from_code(map.pop(&('C' as u8)).unwrap().as_slice()),
message: map.pop(&('M' as u8)).unwrap(),
detail: map.pop(&('D' as u8)),
hint: map.pop(&('H' as u8)),
position: match map.pop(&('P' as u8)) {
Some(pos) => Some(Position(FromStr::from_str(pos.as_slice()).unwrap())),
None => match map.pop(&('p' as u8)) {
Ok(PostgresDbError {
severity: try!(map.pop(&b'S').ok_or(())),
code: PostgresSqlState::from_code(try!(map.pop(&b'C').ok_or(())).as_slice()),
message: try!(map.pop(&b'M').ok_or(())),
detail: map.pop(&b'D'),
hint: map.pop(&b'H'),
position: match map.pop(&b'P') {
Some(pos) => Some(Position(try!(from_str(pos.as_slice()).ok_or(())))),
None => match map.pop(&b'p') {
Some(pos) => Some(InternalPosition {
position: FromStr::from_str(pos.as_slice()).unwrap(),
query: map.pop(&('q' as u8)).unwrap()
position: try!(from_str(pos.as_slice()).ok_or(())),
query: try!(map.pop(&b'q').ok_or(()))
}),
None => None
}
},
where_: map.pop(&('W' as u8)),
schema: map.pop(&('s' as u8)),
table: map.pop(&('t' as u8)),
column: map.pop(&('c' as u8)),
datatype: map.pop(&('d' as u8)),
constraint: map.pop(&('n' as u8)),
file: map.pop(&('F' as u8)).unwrap(),
line: FromStr::from_str(map.pop(&('L' as u8)).unwrap().as_slice()).unwrap(),
routine: map.pop(&('R' as u8)).unwrap()
where_: map.pop(&b'W'),
schema: map.pop(&b's'),
table: map.pop(&b't'),
column: map.pop(&b'c'),
datatype: map.pop(&b'd'),
constraint: map.pop(&b'n'),
file: try!(map.pop(&b'F').ok_or(())),
line: try!(map.pop(&b'L').and_then(|l| from_str(l.as_slice())).ok_or(())),
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,
MissingPassword,
MissingUser,
PgConnectDbError,
PgConnectStreamError,
PgConnectBadResponse,
PgDbError,
PgInvalidColumn,
PgStreamDesynchronized,
PgStreamError,
@ -428,7 +426,7 @@ impl InnerPostgresConnection {
}
ReadyForQuery { .. } => break,
ErrorResponse { fields } =>
return Err(PgConnectDbError(PostgresDbError::new(fields))),
return PostgresDbError::new_connect(fields),
_ => return Err(PgConnectBadResponse),
}
}
@ -449,7 +447,10 @@ impl InnerPostgresConnection {
loop {
match try_desync!(self, self.stream.read_message()) {
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 } => {
self.notifications.push(PostgresNotification {
@ -500,7 +501,7 @@ impl InnerPostgresConnection {
| AuthenticationSCMCredential
| AuthenticationGSS
| AuthenticationSSPI => return Err(UnsupportedAuthentication),
ErrorResponse { fields } => return Err(PgConnectDbError(PostgresDbError::new(fields))),
ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
_ => {
self.desynchronized = true;
return Err(PgConnectBadResponse);
@ -509,7 +510,7 @@ impl InnerPostgresConnection {
match try_pg_conn!(self.read_message_()) {
AuthenticationOk => Ok(()),
ErrorResponse { fields } => Err(PgConnectDbError(PostgresDbError::new(fields))),
ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
_ => {
self.desynchronized = true;
return Err(PgConnectBadResponse);
@ -543,7 +544,7 @@ impl InnerPostgresConnection {
ParseComplete => {}
ErrorResponse { fields } => {
try!(self.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
_ => bad_response!(self),
}
@ -629,7 +630,7 @@ impl InnerPostgresConnection {
ReadyForQuery { .. } => break,
ErrorResponse { fields } => {
try!(self.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
_ => {}
}
@ -691,7 +692,7 @@ impl InnerPostgresConnection {
}
ErrorResponse { fields } => {
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(()),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
Err(PgDbError(PostgresDbError::new(fields)))
PostgresDbError::new(fields)
}
_ => {
conn.desynchronized = true;
@ -1251,7 +1252,7 @@ impl<'conn> PostgresStatement<'conn> {
DataRow { .. } => {}
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
CommandComplete { tag } => {
num = util::parse_update_count(tag);
@ -1357,7 +1358,7 @@ impl<'stmt> PostgresRows<'stmt> {
ReadyForQuery { .. } => break,
ErrorResponse { fields } => {
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),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
CopyInResponse { .. } => {
try_pg!(conn.write_messages([
@ -1622,7 +1623,7 @@ impl<'a> PostgresCopyInStatement<'a> {
BindComplete => {},
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
_ => {
conn.desynchronized = true;
@ -1692,7 +1693,7 @@ impl<'a> PostgresCopyInStatement<'a> {
CommandComplete { tag } => util::parse_update_count(tag),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return Err(PgDbError(PostgresDbError::new(fields)));
return PostgresDbError::new(fields);
}
_ => {
conn.desynchronized = true;