Skip to content

Commit

Permalink
Switch to thiserror for error handling #100
Browse files Browse the repository at this point in the history
  • Loading branch information
suharev7 committed Jun 9, 2020
1 parent 34420c4 commit 05b0ad1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 57 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ lz4 = "1.23.1"
clickhouse-rs-cityhash-sys = { path = "clickhouse-rs-cityhash-sys", version = "0.1.2" }

byteorder = "1.3.1"
failure = "0.1"
failure_derive = "0.1"
thiserror = "1.0.19"
url="^2"
lazy_static = "1.4.0"

Expand Down
92 changes: 46 additions & 46 deletions src/errors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{borrow::Cow, io, mem, result, str::Utf8Error, string::FromUtf8Error, sync::Arc};

use failure::*;
use thiserror::Error;
use tokio::prelude::*;
use tokio_timer::{timeout::Error as TimeoutError, Error as TimerError};
use url::ParseError;
Expand All @@ -14,33 +14,33 @@ pub mod codes;
pub type Result<T> = result::Result<T, Error>;

/// This type enumerates library errors.
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
pub enum Error {
#[fail(display = "Driver error: `{}`", _0)]
Driver(#[cause] DriverError),
#[error("Driver error: `{}`", _0)]
Driver(#[source] DriverError),

#[fail(display = "Input/output error: `{}`", _0)]
Io(#[cause] io::Error),
#[error("Input/output error: `{}`", _0)]
Io(#[source] io::Error),

#[fail(display = "Connections error: `{}`", _0)]
Connection(#[cause] ConnectionError),
#[error("Connections error: `{}`", _0)]
Connection(#[source] ConnectionError),

#[fail(display = "Other error: `{}`", _0)]
Other(#[cause] failure::Error),
#[error("Other error: `{}`", _0)]
Other(Cow<'static, str>),

#[fail(display = "Server error: `{}`", _0)]
Server(#[cause] ServerError),
#[error("Server error: `{}`", _0)]
Server(#[source] ServerError),

#[fail(display = "URL error: `{}`", _0)]
Url(#[cause] UrlError),
#[error("URL error: `{}`", _0)]
Url(#[source] UrlError),

#[fail(display = "From SQL error: `{}`", _0)]
FromSql(#[cause] FromSqlError),
#[error("From SQL error: `{}`", _0)]
FromSql(#[source] FromSqlError),
}

/// This type represents Clickhouse server error.
#[derive(Debug, Fail, Clone)]
#[fail(display = "ERROR {} ({}): {}", name, code, message)]
#[derive(Debug, Error, Clone)]
#[error("ERROR {} ({}): {}", name, code, message)]
pub struct ServerError {
pub code: u32,
pub name: String,
Expand All @@ -50,73 +50,73 @@ pub struct ServerError {
}

/// This type enumerates connection errors.
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
pub enum ConnectionError {
#[fail(display = "TLS connection requires hostname to be provided")]
#[error("TLS connection requires hostname to be provided")]
TlsHostNotProvided,

#[fail(display = "Input/output error: `{}`", _0)]
IoError(#[cause] io::Error),
#[error("Input/output error: `{}`", _0)]
IoError(#[source] io::Error),

#[cfg(feature = "tls")]
#[fail(display = "TLS connection error: `{}`", _0)]
TlsError(#[cause] native_tls::Error),
#[error("TLS connection error: `{}`", _0)]
TlsError(#[source] native_tls::Error),
}

/// This type enumerates connection URL errors.
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
pub enum UrlError {
#[fail(display = "Invalid or incomplete connection URL")]
#[error("Invalid or incomplete connection URL")]
Invalid,

#[fail(
display = "Invalid value `{}' for connection URL parameter `{}'",
#[error(
"Invalid value `{}' for connection URL parameter `{}'",
value, param
)]
InvalidParamValue { param: String, value: String },

#[fail(display = "URL parse error: {}", _0)]
Parse(#[cause] ParseError),
#[error("URL parse error: {}", _0)]
Parse(#[source] ParseError),

#[fail(display = "Unknown connection URL parameter `{}'", param)]
#[error("Unknown connection URL parameter `{}'", param)]
UnknownParameter { param: String },

#[fail(display = "Unsupported connection URL scheme `{}'", scheme)]
#[error("Unsupported connection URL scheme `{}'", scheme)]
UnsupportedScheme { scheme: String },
}

/// This type enumerates driver errors.
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
pub enum DriverError {
#[fail(display = "Varint overflows a 64-bit integer.")]
#[error("Varint overflows a 64-bit integer.")]
Overflow,

#[fail(display = "Unknown packet 0x{:x}.", packet)]
#[error("Unknown packet 0x{:x}.", packet)]
UnknownPacket { packet: u64 },

#[fail(display = "Unexpected packet.")]
#[error("Unexpected packet.")]
UnexpectedPacket,

#[fail(display = "Timeout error.")]
#[error("Timeout error.")]
Timeout,

#[fail(display = "Invalid utf-8 sequence.")]
#[error("Invalid utf-8 sequence.")]
Utf8Error(Utf8Error),
}

/// This type enumerates cast from sql type errors.
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
pub enum FromSqlError {
#[fail(display = "SqlType::{} cannot be cast to {}.", src, dst)]
#[error("SqlType::{} cannot be cast to {}.", src, dst)]
InvalidType {
src: Cow<'static, str>,
dst: Cow<'static, str>,
},

#[fail(display = "Out of range.")]
#[error("Out of range.")]
OutOfRange,

#[fail(display = "Unsupported operation.")]
#[error("Unsupported operation.")]
UnsupportedOperation,
}

Expand Down Expand Up @@ -146,25 +146,25 @@ impl From<UrlError> for Error {

impl From<String> for Error {
fn from(err: String) -> Self {
Error::Other(failure::Context::new(err).into())
Error::Other(Cow::from(err))
}
}

impl From<&str> for Error {
fn from(err: &str) -> Self {
Error::Other(failure::Context::new(err.to_string()).into())
Error::Other(err.to_string().into())
}
}

impl From<FromUtf8Error> for Error {
fn from(err: FromUtf8Error) -> Self {
Error::Other(failure::Context::new(err).into())
Error::Other(err.to_string().into())
}
}

impl From<TimerError> for Error {
fn from(err: TimerError) -> Self {
Error::Other(failure::Context::new(err).into())
Error::Other(err.to_string().into())
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ extern crate chrono;
extern crate chrono_tz;
extern crate clickhouse_rs_cityhash_sys;
extern crate core;
extern crate failure;
#[macro_use]
extern crate futures;
extern crate hostname;
Expand All @@ -131,7 +130,7 @@ extern crate tokio;
extern crate tokio_timer;
extern crate url;

use std::fmt;
use std::{fmt, time::Duration};

use futures::{Future, Stream};
use tokio::prelude::*;
Expand All @@ -148,7 +147,6 @@ use crate::{
OptionsSource, Packet, Query, QueryResult,
},
};
use failure::_core::time::Duration;

mod binary;
mod client_info;
Expand Down Expand Up @@ -579,8 +577,7 @@ fn column_name_to_string(name: &str) -> Result<String, Error> {
}

if name.chars().any(|ch| ch == '`') {
let err = "Column name shouldn't contains backticks.".to_string();
return Err(Error::Other(failure::Context::new(err).into()));
return Err(Error::Other("Column name shouldn't contains backticks.".into()));
}

Ok(format!("`{}`", name))
Expand Down
3 changes: 1 addition & 2 deletions src/types/decimal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use failure::_core::cmp::Ordering;
use std::fmt;
use std::{fmt, cmp::Ordering};

static FACTORS10: &[i64] = &[
1,
Expand Down
4 changes: 2 additions & 2 deletions src/types/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl Certificate {
pub fn from_der(der: &[u8]) -> Result<Certificate> {
let inner = match native_tls::Certificate::from_der(der) {
Ok(certificate) => certificate,
Err(err) => return Err(Error::Other(err.into())),
Err(err) => return Err(Error::Other(err.to_string().into())),
};
Ok(Certificate(Arc::new(inner)))
}
Expand All @@ -115,7 +115,7 @@ impl Certificate {
pub fn from_pem(der: &[u8]) -> Result<Certificate> {
let inner = match native_tls::Certificate::from_pem(der) {
Ok(certificate) => certificate,
Err(err) => return Err(Error::Other(err.into())),
Err(err) => return Err(Error::Other(err.to_string().into())),
};
Ok(Certificate(Arc::new(inner)))
}
Expand Down

0 comments on commit 05b0ad1

Please sign in to comment.