From 4769d25f50fc0c424653d81e67cfa8ad36c31fba Mon Sep 17 00:00:00 2001 From: dalance Date: Wed, 15 Jun 2022 12:20:22 +0900 Subject: [PATCH] Change from failure to thiserror --- Cargo.lock | 102 +---------------------- Cargo.toml | 3 +- examples/findports.rs | 11 +-- src/docker.rs | 34 ++++---- src/errors.rs | 188 +++++++++--------------------------------- src/hyper_client.rs | 6 +- src/stats.rs | 6 +- 7 files changed, 64 insertions(+), 286 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a1ab8a..e89ddfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "aho-corasick" version = "0.7.18" @@ -43,21 +28,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.13.0" @@ -158,7 +128,6 @@ dependencies = [ "chrono", "dirs", "env_logger", - "failure", "futures", "http", "hyper", @@ -174,6 +143,7 @@ dependencies = [ "serde", "serde_json", "tar", + "thiserror", "tokio", "unix_socket", "url", @@ -192,28 +162,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fastrand" version = "1.7.0" @@ -366,12 +314,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "gimli" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -560,15 +502,6 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - [[package]] name = "mio" version = "0.8.3" @@ -649,15 +582,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.12.0" @@ -876,12 +800,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - [[package]] name = "ryu" version = "1.0.10" @@ -1000,18 +918,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "tar" version = "0.4.38" @@ -1186,12 +1092,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" - [[package]] name = "unix_socket" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 9419e47..3e2481b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ ssl = ["openssl", "native-tls", "hyper-tls"] [dependencies] chrono = "0.4" -failure = "0.1" futures = "0.3" http = "0.2" hyper = { version = "0.14", features = ["client", "http1", "stream", "tcp"] } @@ -45,9 +44,9 @@ native-tls = { version = "0.2", optional = true } nix = "0.24" base64 = "0.13" dirs = "4" +thiserror = "1" [dev-dependencies] -failure = "0.1" env_logger = "0.9" rand = "0.8" diff --git a/examples/findports.rs b/examples/findports.rs index 5be2b60..ee79b2f 100644 --- a/examples/findports.rs +++ b/examples/findports.rs @@ -1,9 +1,7 @@ extern crate dockworker; -extern crate failure; use dockworker::errors::*; use dockworker::{container::ContainerFilters, Docker}; -use failure::Fail; fn find_all_exported_ports() -> Result<()> { let docker = Docker::connect_with_defaults()?; @@ -22,11 +20,6 @@ fn find_all_exported_ports() -> Result<()> { Ok(()) } -fn main() { - if let Err(err) = find_all_exported_ports() { - eprint!("Error: "); - for e in ::iter_causes(&err) { - eprintln!("{}", e); - } - } +fn main() -> Result<()> { + find_all_exported_ports() } diff --git a/src/docker.rs b/src/docker.rs index 2614682..a96d8d1 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -50,7 +50,7 @@ pub fn default_cert_path() -> Result { if let Ok(ref path) = from_env { Ok(PathBuf::from(path)) } else { - let home = dirs::home_dir().ok_or_else(|| ErrorKind::NoCertPath)?; + let home = dirs::home_dir().ok_or_else(|| Error::NoCertPath)?; Ok(home.join(".docker")) } } @@ -188,7 +188,7 @@ impl Docker { Docker::connect_with_http(&host) } } else { - Err(ErrorKind::UnsupportedScheme { host: host.clone() }.into()) + Err(Error::UnsupportedScheme { host: host.clone() }.into()) } } @@ -209,7 +209,7 @@ impl Docker { #[cfg(not(unix))] pub fn connect_with_unix(addr: &str) -> Result { - Err(ErrorKind::UnsupportedScheme { + Err(Error::UnsupportedScheme { host: addr.to_owned(), } .into()) @@ -217,25 +217,28 @@ impl Docker { #[cfg(feature = "openssl")] pub fn connect_with_ssl(addr: &str, key: &Path, cert: &Path, ca: &Path) -> Result { - let client = HyperClient::connect_with_ssl(addr, key, cert, ca).context( - ErrorKind::CouldNotConnect { + let client = HyperClient::connect_with_ssl(addr, key, cert, ca).map_err(|err| { + Error::CouldNotConnect { addr: addr.to_owned(), - }, - )?; + source: err.into(), + } + })?; Ok(Docker::new(client, Protocol::Tcp)) } #[cfg(not(feature = "openssl"))] pub fn connect_with_ssl(_addr: &str, _key: &Path, _cert: &Path, _ca: &Path) -> Result { - Err(ErrorKind::SslDisabled.into()) + Err(Error::SslDisabled.into()) } /// Connect using unsecured HTTP. This is strongly discouraged /// everywhere but on Windows when npipe support is not available. pub fn connect_with_http(addr: &str) -> Result { - let client = HyperClient::connect_with_http(addr).context(ErrorKind::CouldNotConnect { - addr: addr.to_owned(), - })?; + let client = + HyperClient::connect_with_http(addr).map_err(|err| Error::CouldNotConnect { + addr: addr.to_owned(), + source: err.into(), + })?; Ok(Docker::new(client, Protocol::Tcp)) } @@ -745,8 +748,9 @@ impl Docker { .get("X-Docker-Container-Path-Stat") .map(|h| h.to_str().unwrap_or("")) .unwrap_or(""); - let bytes = base64::decode(stat_base64).context(ErrorKind::ParseError { + let bytes = base64::decode(stat_base64).map_err(|err| Error::ParseError { input: String::from(stat_base64), + source: err, })?; let path_stat: XDockerContainerPathStat = serde_json::from_slice(&bytes)?; Ok(path_stat) @@ -1029,13 +1033,13 @@ impl Docker { // looking for file name like XXXXXXXXXXXXXX.json if path.extension() == Some(OsStr::new("json")) && path != Path::new("manifest.json") { let stem = path.file_stem().unwrap(); // contains .json - let id = stem.to_str().ok_or(ErrorKind::Unknown { + let id = stem.to_str().ok_or(Error::Unknown { message: format!("convert to String: {:?}", stem), })?; return Ok(ImageId::new(id.to_string())); } } - Err(ErrorKind::Unknown { + Err(Error::Unknown { message: "no expected file: XXXXXX.json".to_owned(), } .into()) @@ -1713,7 +1717,7 @@ mod tests { assert!(match docker.get_file(&container.id, test_file) { Ok(_) => false, Err(err) => { - if let ErrorKind::Docker = err.kind() { + if let Error::Docker(_) = err { true // not found } else { false diff --git a/src/errors.rs b/src/errors.rs index 4d08bb1..4be5fe2 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,164 +1,50 @@ use crate::docker; use crate::response; -pub use failure::ResultExt; -use failure::{Backtrace, Context, Fail}; use std::env; -use std::fmt; use std::io; +use thiserror::Error; pub type Result = ::std::result::Result; -#[derive(Fail, Debug, Clone)] -pub enum ErrorKind { - #[fail(display = "io error")] - Io, - #[fail(display = "envvar error")] - Envvar, - #[fail(display = "hyper error")] - Hyper, - #[fail(display = "json error")] - Json, - #[fail(display = "docker error")] - Docker, - #[fail(display = "response error")] - Response, - #[fail(display = "http error")] - Http, - #[fail(display = "invalid uri: {}", var)] - InvalidUri { var: String }, - #[fail(display = "ssl error")] - SSL, - #[fail(display = "could not connect: {}", addr)] - CouldNotConnect { addr: String }, - #[fail(display = "could not find DOCKER_CERT_PATH")] +#[derive(Error, Debug)] +pub enum Error { + #[error("io error")] + Io(#[from] io::Error), + #[error("envvar error")] + Envvar(#[from] env::VarError), + #[error("hyper error")] + Hyper(#[from] hyper::Error), + #[error("json error")] + Json(#[from] serde_json::Error), + #[error("docker error")] + Docker(#[from] docker::DockerError), + #[error("response error")] + Response(#[from] response::Error), + #[error("http error")] + Http(#[from] http::Error), + #[error("invalid uri")] + InvalidUri(#[from] http::uri::InvalidUri), + #[cfg(feature = "native-tls")] + #[error("ssl error")] + NativeTls(#[from] native_tls::Error), + #[cfg(feature = "openssl")] + #[error("ssl error")] + OpenSsl(#[from] openssl::error::ErrorStack), + #[error("could not connect: {}", addr)] + CouldNotConnect { addr: String, source: Box }, + #[error("could not find DOCKER_CERT_PATH")] NoCertPath, - #[fail(display = "parse error: {}", input)] - ParseError { input: String }, - #[fail(display = "ssl support was disabled at compile time")] + #[error("parse error: {}", input)] + ParseError { + input: String, + source: base64::DecodeError, + }, + #[error("ssl support was disabled at compile time")] SslDisabled, - #[fail(display = "unsupported scheme: {}", host)] + #[error("unsupported scheme: {}", host)] UnsupportedScheme { host: String }, - #[fail(display = "poison error: {}", message)] + #[error("poison error: {}", message)] Poison { message: String }, - #[fail(display = "unknown error: {}", message)] + #[error("unknown error: {}", message)] Unknown { message: String }, } - -#[derive(Debug)] -pub struct Error { - inner: Context, -} - -impl Fail for Error { - fn cause(&self) -> Option<&(dyn Fail + 'static)> { - self.inner.cause() - } - - fn backtrace(&self) -> Option<&Backtrace> { - self.inner.backtrace() - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.inner, f) - } -} - -impl Error { - pub fn new(inner: Context) -> Error { - Error { inner } - } - - pub fn kind(&self) -> &ErrorKind { - self.inner.get_context() - } -} - -impl From for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner } - } -} - -impl From for Error { - fn from(error: io::Error) -> Self { - Error { - inner: error.context(ErrorKind::Io), - } - } -} - -impl From for Error { - fn from(error: env::VarError) -> Self { - Error { - inner: error.context(ErrorKind::Envvar), - } - } -} - -impl From for Error { - fn from(error: hyper::Error) -> Self { - Error { - inner: error.context(ErrorKind::Hyper), - } - } -} - -impl From<::serde_json::Error> for Error { - fn from(error: ::serde_json::Error) -> Self { - Error { - inner: error.context(ErrorKind::Json), - } - } -} - -impl From for Error { - fn from(error: docker::DockerError) -> Self { - Error { - inner: error.context(ErrorKind::Docker), - } - } -} - -impl From for Error { - fn from(error: response::Error) -> Self { - Error { - inner: error.context(ErrorKind::Response), - } - } -} - -impl From for Error { - fn from(error: http::Error) -> Self { - Error { - inner: error.context(ErrorKind::Http), - } - } -} - -#[cfg(feature = "openssl")] -impl From for Error { - fn from(error: native_tls::Error) -> Self { - Error { - inner: error.context(ErrorKind::SSL), - } - } -} - -#[cfg(feature = "openssl")] -impl From for Error { - fn from(error: openssl::error::ErrorStack) -> Self { - Error { - inner: error.context(ErrorKind::SSL), - } - } -} diff --git a/src/hyper_client.rs b/src/hyper_client.rs index be25564..b53d442 100644 --- a/src/hyper_client.rs +++ b/src/hyper_client.rs @@ -138,7 +138,7 @@ pub struct HyperClient { fn join_uri(uri: &Uri, path: &str) -> Result { let joined = format!("{}{}", uri.to_string(), path); - Ok(Uri::from_str(&joined).context(ErrorKind::InvalidUri { var: joined })?) + Ok(Uri::from_str(&joined)?) } fn request_builder( @@ -273,7 +273,7 @@ impl HyperClient { builder.add_root_certificate(ca); // This ensures that using docker-machine-esque addresses work with Hyper. let addr_https = addr.clone().replacen("tcp://", "https://", 1); - let url = Uri::from_str(&addr_https).context(ErrorKind::InvalidUri { var: addr_https })?; + let url = Uri::from_str(&addr_https)?; let mut http = hyper::client::HttpConnector::new(); http.enforce_http(false); let https = hyper_tls::HttpsConnector::from((http, builder.build()?.into())); @@ -284,7 +284,7 @@ impl HyperClient { pub fn connect_with_http(addr: &str) -> result::Result { // This ensures that using docker-machine-esque addresses work with Hyper. let addr_https = addr.clone().replace("tcp://", "http://"); - let url = Uri::from_str(&addr_https).context(ErrorKind::InvalidUri { var: addr_https })?; + let url = Uri::from_str(&addr_https)?; Ok(Self::new(Client::HttpClient(hyper::Client::new()), url)) } } diff --git a/src/stats.rs b/src/stats.rs index e96595a..45c3b4c 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -27,11 +27,7 @@ impl iter::Iterator for StatsReader { let mut line = String::new(); match self.buf.read_line(&mut line) { Ok(0) => None, - Ok(_) => Some( - serde_json::from_str::(&line) - .context(ErrorKind::ParseError { input: line }) - .map_err(Into::into), - ), + Ok(_) => Some(serde_json::from_str::(&line).map_err(Into::into)), Err(err) => Some(Err(err.into())), } }