Flatten and rename error stuff

This commit is contained in:
Steven Fackler 2014-11-03 22:24:11 -08:00
parent 056f90a3a2
commit a4fe4e2056
4 changed files with 80 additions and 82 deletions

View File

@ -16,21 +16,21 @@ macro_rules! make_errors(
/// SQLSTATE error codes
#[deriving(PartialEq, Eq, Clone, Show)]
#[allow(missing_docs)]
pub enum PostgresSqlState {
pub enum SqlState {
$($error,)+
UnknownSqlState(String)
Unknown(String)
}
static STATE_MAP: phf::Map<&'static str, PostgresSqlState> = phf_map!(
$($code => $error),+
static STATE_MAP: phf::Map<&'static str, SqlState> = phf_map!(
$($code => SqlState::$error),+
);
impl PostgresSqlState {
impl SqlState {
#[doc(hidden)]
pub fn from_code(s: &str) -> PostgresSqlState {
pub fn from_code(s: &str) -> SqlState {
match STATE_MAP.find_equiv(s) {
Some(state) => state.clone(),
None => UnknownSqlState(s.into_string())
None => SqlState::Unknown(s.into_string())
}
}
}
@ -358,7 +358,7 @@ make_errors!(
/// Reasons a new Postgres connection could fail
#[deriving(Clone, PartialEq, Eq)]
pub enum PostgresConnectError {
pub enum ConnectError {
/// The provided URL could not be parsed
InvalidUrl(String),
/// The URL was missing a user
@ -366,7 +366,7 @@ pub enum PostgresConnectError {
/// There was an error opening a socket to the server
SocketError(io::IoError),
/// An error from the Postgres server itself
PgConnectDbError(PostgresDbError),
PgConnectDbError(DbError),
/// A password was required but not provided in the URL
MissingPassword,
/// The Postgres server requested an authentication method not supported
@ -382,7 +382,7 @@ pub enum PostgresConnectError {
PgConnectBadResponse,
}
impl fmt::Show for PostgresConnectError {
impl fmt::Show for ConnectError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
InvalidUrl(ref err) => write!(fmt, "Invalid URL: {}", err),
@ -408,11 +408,11 @@ impl fmt::Show for PostgresConnectError {
/// Represents the position of an error in a query
#[deriving(Clone, PartialEq, Eq)]
pub enum PostgresErrorPosition {
pub enum ErrorPosition {
/// A position in the original query
Position(uint),
Normal(uint),
/// A position in an internally generated query
InternalPosition {
Internal {
/// The byte position
pub position: uint,
/// A query generated by the Postgres server
@ -422,13 +422,13 @@ pub enum PostgresErrorPosition {
/// Encapsulates a Postgres error or notice.
#[deriving(Clone, PartialEq, Eq)]
pub struct PostgresDbError {
pub struct DbError {
/// The field contents are ERROR, FATAL, or PANIC (in an error message),
/// or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a
/// localized translation of one of these.
pub severity: String,
/// The SQLSTATE code for the error.
pub code: PostgresSqlState,
pub code: SqlState,
/// The primary human-readable error message. This should be accurate but
/// terse (typically one line).
pub message: String,
@ -441,7 +441,7 @@ pub struct PostgresDbError {
pub hint: Option<String>,
/// An optional error cursor position into either the original query string
/// or an internally generated query.
pub position: Option<PostgresErrorPosition>,
pub position: Option<ErrorPosition>,
/// An indication of the context in which the error occurred. Presently
/// this includes a call stack traceback of active procedural language
/// functions and internally-generated queries. The trace is one entry per
@ -476,20 +476,20 @@ pub struct PostgresDbError {
pub routine: String
}
impl PostgresDbError {
impl DbError {
#[doc(hidden)]
pub fn new_raw(fields: Vec<(u8, String)>) -> result::Result<PostgresDbError, ()> {
pub fn new_raw(fields: Vec<(u8, String)>) -> result::Result<DbError, ()> {
let mut map: HashMap<_, _> = fields.into_iter().collect();
Ok(PostgresDbError {
Ok(DbError {
severity: try!(map.pop(&b'S').ok_or(())),
code: PostgresSqlState::from_code(try!(map.pop(&b'C').ok_or(()))[]),
code: SqlState::from_code(try!(map.pop(&b'C').ok_or(()))[]),
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[]).ok_or(())))),
Some(pos) => Some(ErrorPosition::Normal(try!(from_str(pos[]).ok_or(())))),
None => match map.pop(&b'p') {
Some(pos) => Some(InternalPosition {
Some(pos) => Some(ErrorPosition::Internal {
position: try!(from_str(pos[]).ok_or(())),
query: try!(map.pop(&b'q').ok_or(()))
}),
@ -509,8 +509,8 @@ impl PostgresDbError {
}
#[doc(hidden)]
pub fn new_connect<T>(fields: Vec<(u8, String)>) -> result::Result<T, PostgresConnectError> {
match PostgresDbError::new_raw(fields) {
pub fn new_connect<T>(fields: Vec<(u8, String)>) -> result::Result<T, ConnectError> {
match DbError::new_raw(fields) {
Ok(err) => Err(PgConnectDbError(err)),
Err(()) => Err(PgConnectBadResponse),
}
@ -518,14 +518,14 @@ impl PostgresDbError {
#[doc(hidden)]
pub fn new<T>(fields: Vec<(u8, String)>) -> Result<T> {
match PostgresDbError::new_raw(fields) {
match DbError::new_raw(fields) {
Ok(err) => Err(PgDbError(err)),
Err(()) => Err(PgBadData),
}
}
}
impl fmt::Show for PostgresDbError {
impl fmt::Show for DbError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}: {}", self.severity, self.message)
}
@ -533,9 +533,9 @@ impl fmt::Show for PostgresDbError {
/// An error encountered when communicating with the Postgres server
#[deriving(Clone, PartialEq, Eq)]
pub enum PostgresError {
pub enum Error {
/// An error reported by the Postgres server
PgDbError(PostgresDbError),
PgDbError(DbError),
/// An error communicating with the Postgres server
PgStreamError(io::IoError),
/// The communication channel with the Postgres server has desynchronized
@ -566,7 +566,7 @@ pub enum PostgresError {
PgBadData,
}
impl fmt::Show for PostgresError {
impl fmt::Show for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
PgDbError(ref err) => err.fmt(fmt),

View File

@ -5,7 +5,7 @@ use std::io::net::pipe;
use std::io::{Stream, IoResult};
use {ConnectParams, SslMode, NoSsl, PreferSsl, RequireSsl, ConnectTarget};
use error::{PostgresConnectError, PgConnectStreamError, NoSslSupport, SslError, SocketError};
use error::{ConnectError, PgConnectStreamError, NoSslSupport, SslError, SocketError};
use message;
use message::{SslRequest, WriteMessage};
@ -72,7 +72,7 @@ impl Writer for InternalStream {
}
fn open_socket(params: &ConnectParams)
-> Result<InternalStream, PostgresConnectError> {
-> Result<InternalStream, ConnectError> {
let port = params.port.unwrap_or(DEFAULT_PORT);
let socket = match params.target {
ConnectTarget::Tcp(ref host) =>
@ -87,7 +87,7 @@ fn open_socket(params: &ConnectParams)
}
pub fn initialize_stream(params: &ConnectParams, ssl: &SslMode)
-> Result<MaybeSslStream<InternalStream>, PostgresConnectError> {
-> Result<MaybeSslStream<InternalStream>, ConnectError> {
let mut socket = try!(open_socket(params));
let (ssl_required, ctx) = match *ssl {

View File

@ -84,9 +84,6 @@ use error::{InvalidUrl,
PgStreamDesynchronized,
PgStreamError,
PgWrongParamCount,
PostgresConnectError,
PostgresDbError,
PostgresError,
UnsupportedAuthentication,
PgWrongConnection,
PgWrongTransaction,
@ -98,6 +95,7 @@ use message::BackendMessage::*;
use message::{WriteMessage, ReadMessage};
#[doc(inline)]
pub use types::{Oid, Type, ToSql, FromSql};
pub use error::{Error, ConnectError, SqlState, DbError, ErrorPosition};
#[macro_escape]
mod macros;
@ -106,13 +104,13 @@ mod io;
mod message;
mod url;
mod util;
pub mod error;
mod error;
pub mod types;
const CANARY: u32 = 0xdeadbeef;
/// A typedef of the result returned by many methods.
pub type Result<T> = result::Result<T, PostgresError>;
pub type Result<T> = result::Result<T, Error>;
/// Specifies the target server to connect to.
#[deriving(Clone)]
@ -154,17 +152,17 @@ 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, PostgresConnectError>;
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError>;
}
impl IntoConnectParams for ConnectParams {
fn into_connect_params(self) -> result::Result<ConnectParams, PostgresConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
Ok(self)
}
}
impl<'a> IntoConnectParams for &'a str {
fn into_connect_params(self) -> result::Result<ConnectParams, PostgresConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
match Url::parse(self) {
Ok(url) => url.into_connect_params(),
Err(err) => return Err(InvalidUrl(err)),
@ -173,7 +171,7 @@ impl<'a> IntoConnectParams for &'a str {
}
impl IntoConnectParams for Url {
fn into_connect_params(self) -> result::Result<ConnectParams, PostgresConnectError> {
fn into_connect_params(self) -> result::Result<ConnectParams, ConnectError> {
let Url {
host,
port,
@ -214,7 +212,7 @@ impl IntoConnectParams for Url {
/// Trait for types that can handle Postgres notice messages
pub trait NoticeHandler {
/// Handle a Postgres notice message
fn handle(&mut self, notice: PostgresDbError);
fn handle(&mut self, notice: DbError);
}
/// A notice handler which logs at the `info` level.
@ -223,7 +221,7 @@ pub trait NoticeHandler {
pub struct DefaultNoticeHandler;
impl NoticeHandler for DefaultNoticeHandler {
fn handle(&mut self, notice: PostgresDbError) {
fn handle(&mut self, notice: DbError) {
info!("{}: {}", notice.severity, notice.message);
}
}
@ -289,7 +287,7 @@ pub struct CancelData {
/// postgres::cancel_query(url, &NoSsl, cancel_data);
/// ```
pub fn cancel_query<T>(params: T, ssl: &SslMode, data: CancelData)
-> result::Result<(), PostgresConnectError> where T: IntoConnectParams {
-> result::Result<(), ConnectError> where T: IntoConnectParams {
let params = try!(params.into_connect_params());
let mut socket = try!(io::initialize_stream(&params, ssl));
@ -326,7 +324,7 @@ impl Drop for InnerConnection {
impl InnerConnection {
fn connect<T>(params: T, ssl: &SslMode)
-> result::Result<InnerConnection, PostgresConnectError>
-> result::Result<InnerConnection, ConnectError>
where T: IntoConnectParams {
let params = try!(params.into_connect_params());
let stream = try!(io::initialize_stream(&params, ssl));
@ -378,7 +376,7 @@ impl InnerConnection {
conn.cancel_data.secret_key = secret_key;
}
ReadyForQuery { .. } => break,
ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
ErrorResponse { fields } => return DbError::new_connect(fields),
_ => return Err(PgConnectBadResponse),
}
}
@ -399,7 +397,7 @@ impl InnerConnection {
loop {
match try_desync!(self, self.stream.read_message()) {
NoticeResponse { fields } => {
if let Ok(err) = PostgresDbError::new_raw(fields) {
if let Ok(err) = DbError::new_raw(fields) {
self.notice_handler.handle(err);
}
}
@ -418,7 +416,7 @@ impl InnerConnection {
}
}
fn handle_auth(&mut self, user: UserInfo) -> result::Result<(), PostgresConnectError> {
fn handle_auth(&mut self, user: UserInfo) -> result::Result<(), ConnectError> {
match try_pg_conn!(self.read_message()) {
AuthenticationOk => return Ok(()),
AuthenticationCleartextPassword => {
@ -446,7 +444,7 @@ impl InnerConnection {
| AuthenticationSCMCredential
| AuthenticationGSS
| AuthenticationSSPI => return Err(UnsupportedAuthentication),
ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
ErrorResponse { fields } => return DbError::new_connect(fields),
_ => {
self.desynchronized = true;
return Err(PgConnectBadResponse);
@ -455,7 +453,7 @@ impl InnerConnection {
match try_pg_conn!(self.read_message()) {
AuthenticationOk => Ok(()),
ErrorResponse { fields } => return PostgresDbError::new_connect(fields),
ErrorResponse { fields } => return DbError::new_connect(fields),
_ => {
self.desynchronized = true;
return Err(PgConnectBadResponse);
@ -488,7 +486,7 @@ impl InnerConnection {
ParseComplete => {}
ErrorResponse { fields } => {
try!(self.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => bad_response!(self),
}
@ -573,7 +571,7 @@ impl InnerConnection {
ReadyForQuery { .. } => break,
ErrorResponse { fields } => {
try!(self.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => {}
}
@ -640,7 +638,7 @@ impl InnerConnection {
}
ErrorResponse { fields } => {
try!(self.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => {}
}
@ -716,7 +714,7 @@ impl Connection {
/// let conn = try!(Connection::connect(params, &NoSsl));
/// # Ok(()) };
/// ```
pub fn connect<T>(params: T, ssl: &SslMode) -> result::Result<Connection, PostgresConnectError>
pub fn connect<T>(params: T, ssl: &SslMode) -> result::Result<Connection, ConnectError>
where T: IntoConnectParams {
InnerConnection::connect(params, ssl).map(|conn| {
Connection { conn: RefCell::new(conn) }
@ -808,7 +806,7 @@ impl Connection {
///
/// ```rust,no_run
/// # use postgres::{Connection, NoSsl};
/// # fn foo() -> Result<(), postgres::error::PostgresError> {
/// # fn foo() -> Result<(), postgres::Error> {
/// # let conn = Connection::connect("", &NoSsl).unwrap();
/// let trans = try!(conn.transaction());
/// try!(trans.execute("UPDATE foo SET bar = 10", []));
@ -1129,7 +1127,7 @@ impl<'conn> Statement<'conn> {
BindComplete => Ok(()),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
PostgresDbError::new(fields)
DbError::new(fields)
}
_ => {
conn.desynchronized = true;
@ -1196,7 +1194,7 @@ impl<'conn> Statement<'conn> {
DataRow { .. } => {}
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
CommandComplete { tag } => {
num = util::parse_update_count(tag);
@ -1302,7 +1300,7 @@ impl<'stmt> Rows<'stmt> {
ReadyForQuery { .. } => break,
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => {}
}
@ -1326,7 +1324,7 @@ impl<'stmt> Rows<'stmt> {
DataRow { row } => self.data.push(row),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
CopyInResponse { .. } => {
try_pg!(conn.write_messages([
@ -1555,7 +1553,7 @@ impl<'a> CopyInStatement<'a> {
BindComplete => {},
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => {
conn.desynchronized = true;
@ -1633,7 +1631,7 @@ impl<'a> CopyInStatement<'a> {
CommandComplete { tag } => util::parse_update_count(tag),
ErrorResponse { fields } => {
try!(conn.wait_for_ready());
return PostgresDbError::new(fields);
return DbError::new(fields);
}
_ => {
conn.desynchronized = true;

View File

@ -20,24 +20,24 @@ use postgres::{NoticeHandler,
PreferSsl,
NoSsl,
Type,
ToSql};
use postgres::error::{PgConnectDbError,
PgDbError,
ToSql,
DbError};
use postgres::ConnectError::{PgConnectDbError,
MissingPassword};
use postgres::Error::{PgDbError,
PgWrongConnection,
PgWrongParamCount,
PgWrongType,
PgInvalidColumn,
PgWasNull,
MissingPassword,
Position,
PostgresDbError,
SyntaxError,
InvalidPassword,
PgWrongTransaction};
use postgres::SqlState::{SyntaxError,
QueryCanceled,
UndefinedTable,
InvalidCatalogName,
PgWrongTransaction,
InvalidPassword,
CardinalityViolation};
use postgres::ErrorPosition::Normal;
macro_rules! or_panic(
($e:expr) => (
@ -64,7 +64,7 @@ fn test_url_terminating_slash() {
fn test_prepare_err() {
let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &NoSsl));
match conn.prepare("invalid sql statment") {
Err(PgDbError(PostgresDbError { code: SyntaxError, position: Some(Position(1)), .. })) => (),
Err(PgDbError(DbError { code: SyntaxError, position: Some(Normal(1)), .. })) => (),
Err(e) => panic!("Unexpected result {}", e),
_ => panic!("Unexpected result"),
}
@ -73,7 +73,7 @@ fn test_prepare_err() {
#[test]
fn test_unknown_database() {
match Connection::connect("postgres://postgres@localhost/asdf", &NoSsl) {
Err(PgConnectDbError(PostgresDbError { code: InvalidCatalogName, .. })) => {}
Err(PgConnectDbError(DbError { code: InvalidCatalogName, .. })) => {}
Err(resp) => panic!("Unexpected result {}", resp),
_ => panic!("Unexpected result"),
}
@ -350,7 +350,7 @@ fn test_batch_execute_error() {
conn.batch_execute(query).unwrap_err();
match conn.prepare("SELECT * from foo ORDER BY id") {
Err(PgDbError(PostgresDbError { code: UndefinedTable, .. })) => {},
Err(PgDbError(DbError { code: UndefinedTable, .. })) => {},
Err(e) => panic!("unexpected error {}", e),
_ => panic!("unexpected success"),
}
@ -393,7 +393,7 @@ FROM (SELECT gs.i
ORDER BY gs.i
LIMIT 2) ss"));
match stmt.query([]) {
Err(PgDbError(PostgresDbError { code: CardinalityViolation, .. })) => {}
Err(PgDbError(DbError { code: CardinalityViolation, .. })) => {}
Err(err) => panic!("Unexpected error {}", err),
Ok(_) => panic!("Expected failure"),
}
@ -543,7 +543,7 @@ fn test_custom_notice_handler() {
struct Handler;
impl NoticeHandler for Handler {
fn handle(&mut self, notice: PostgresDbError) {
fn handle(&mut self, notice: DbError) {
assert_eq!("note", notice.message[]);
unsafe { count += 1; }
}
@ -622,7 +622,7 @@ fn test_cancel_query() {
});
match conn.execute("SELECT pg_sleep(10)", []) {
Err(PgDbError(PostgresDbError { code: QueryCanceled, .. })) => {}
Err(PgDbError(DbError { code: QueryCanceled, .. })) => {}
Err(res) => panic!("Unexpected result {}", res),
_ => panic!("Unexpected result"),
}
@ -663,7 +663,7 @@ fn test_plaintext_pass_no_pass() {
fn test_plaintext_pass_wrong_pass() {
let ret = Connection::connect("postgres://pass_user:asdf@localhost/postgres", &NoSsl);
match ret {
Err(PgConnectDbError(PostgresDbError { code: InvalidPassword, .. })) => (),
Err(PgConnectDbError(DbError { code: InvalidPassword, .. })) => (),
Err(err) => panic!("Unexpected error {}", err),
_ => panic!("Expected error")
}
@ -688,7 +688,7 @@ fn test_md5_pass_no_pass() {
fn test_md5_pass_wrong_pass() {
let ret = Connection::connect("postgres://md5_user:asdf@localhost/postgres", &NoSsl);
match ret {
Err(PgConnectDbError(PostgresDbError { code: InvalidPassword, .. })) => (),
Err(PgConnectDbError(DbError { code: InvalidPassword, .. })) => (),
Err(err) => panic!("Unexpected error {}", err),
_ => panic!("Expected error")
}