parent
5561e7baca
commit
a64ca5f955
60
src/error.rs
60
src/error.rs
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
src/lib.rs
31
src/lib.rs
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user