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