From a43ed4755fd8805cdd6f31c26873edb202b75bd1 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Sat, 18 Mar 2017 13:56:34 +0400 Subject: Changed error handling to error-chain crate instead of hand-rolled errors impl (#2) Also made 0.x dependencies more specific - in Rust a bump from 0.x to 0.y means potential breaking changes. --- Cargo.toml | 9 +++--- src/error.rs | 93 +++++++++------------------------------------------------- src/lib.rs | 13 ++++---- src/main.rs | 11 +++---- tests/error.rs | 13 ++++---- 5 files changed, 38 insertions(+), 101 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index afc2faa..9111850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ name = "userspace-wg" [dependencies] clap = { version = "2", features = ["yaml"] } -daemonize = "0" -libc = "0" -log = "0" +daemonize = "0.2" +libc = "0.2" +log = "0.3" mowl = "1" -nix = "0" +nix = "0.8" +error-chain = "0.10" diff --git a/src/error.rs b/src/error.rs index 2a8d5b4..db5edba 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,90 +1,25 @@ -//! Everything related to error handling -use std::error::Error; -use std::{ffi, fmt, io, net, convert}; +//! Everything related to error handling. + +use std::{ffi, io, net}; use daemonize; use log; use nix; -/// Common Tunnel Result type -pub type WgResult = Result; - -/// The global Error type for wiki -pub struct WgError { - /// A further description for the error - description: String, - - #[allow(dead_code)] - /// The cause for this error - cause: Option>, -} - -/// Representation of an error case -impl WgError { - /// Creates a new `WgError` - pub fn new(description: &str) -> Self { - WgError { - description: description.to_string(), - cause: None, - } - } - - /// Returns the corresponding `io::ErrorKind` for this error - pub fn kind(&self) -> io::ErrorKind { - io::ErrorKind::Other +error_chain! { + foreign_links { + Daemonize(daemonize::DaemonizeError) #[doc="A daemonization error."]; + Nul(ffi::NulError) #[doc="An FFI null error."]; + Io(io::Error) #[doc="An I/O error."]; + Log(log::SetLoggerError) #[doc="A log configuration error."]; + AddrParse(net::AddrParseError) #[doc="An address parsing error."]; + Nix(nix::Error) #[doc="A `nix` crate error."]; } } -impl fmt::Display for WgError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.description) +impl From for io::Error { + fn from(error: Error) -> Self { + io::Error::new(io::ErrorKind::Other, error.description()) } } -impl fmt::Debug for WgError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl convert::From for io::Error { - fn from(tunnel_error: WgError) -> Self { - io::Error::new(io::ErrorKind::Other, tunnel_error.description) - } -} - -impl Error for WgError { - fn description(&self) -> &str { - &self.description - } -} - -macro_rules! from_error { - ($($p:ty,)*) => ( - $(impl From<$p> for WgError { - fn from(err: $p) -> Self { - WgError { - description: err.description().to_owned(), - cause: Some(Box::new(err)), - } - } - })* - ) -} - -from_error! { - daemonize::DaemonizeError, - ffi::NulError, - io::Error, - log::SetLoggerError, - net::AddrParseError, - nix::Error, -} - -#[macro_export] -macro_rules! bail { - ($($fmt:tt)*) => ( - #[cfg_attr(feature = "cargo-clippy", allow(useless_format))] - return Err(::error::WgError::new(&format!($($fmt)*))) - ) -} diff --git a/src/lib.rs b/src/lib.rs index d1c9754..9367b78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,13 @@ extern crate daemonize; extern crate log; extern crate libc; extern crate nix; - #[macro_use] +extern crate error_chain; + pub mod error; mod uapi; -pub use error::{WgResult, WgError}; +use error::*; use uapi::{WgDevice, WgIpMask, WgPeer}; use std::fs::{create_dir, remove_file}; @@ -35,7 +36,7 @@ pub struct WireGuard { impl WireGuard { /// Creates a new `WireGuard` instance - pub fn new(name: &str) -> WgResult { + pub fn new(name: &str) -> Result { // Create the unix socket let fd = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), 0)?; if fd < 0 { @@ -84,7 +85,7 @@ impl WireGuard { } /// Run the `WireGuard` instance - pub fn run(&self) -> WgResult<()> { + pub fn run(&self) -> Result<()> { // A temporarily buffer to write in let mut buffer = vec![]; debug!("Waiting for connections."); @@ -193,7 +194,7 @@ impl WireGuard { #[cfg(unix)] /// Sets the permissions to a given `Path` - fn chmod(path: &Path, perms: u32) -> WgResult<()> { + fn chmod(path: &Path, perms: u32) -> Result<()> { use std::os::unix::prelude::PermissionsExt; use std::fs::{set_permissions, Permissions}; set_permissions(path, Permissions::from_mode(perms))?; @@ -202,7 +203,7 @@ impl WireGuard { #[cfg(windows)] /// Sets the permissions to a given `Path` - fn chmod(_path: &Path, _perms: u32) -> WgResult<()> { + fn chmod(_path: &Path, _perms: u32) -> Result<()> { Ok(()) } } diff --git a/src/main.rs b/src/main.rs index a4c9e16..18fff82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,19 +4,20 @@ extern crate clap; extern crate daemonize; extern crate libc; - #[macro_use] extern crate log; extern crate mowl; extern crate nix; - #[macro_use] +extern crate error_chain; + extern crate wireguard; use clap::App; use daemonize::Daemonize; use log::LogLevel; -use wireguard::{WireGuard, WgResult, WgError, error}; +use wireguard::WireGuard; +use wireguard::error::*; use std::process::exit; @@ -27,7 +28,7 @@ fn main() { } } -fn run() -> WgResult<()> { +fn run() -> Result<()> { // Load the CLI parameters from the yaml file let yaml = load_yaml!("cli.yaml"); let app = App::from_yaml(yaml).version(crate_version!()); @@ -48,7 +49,7 @@ fn run() -> WgResult<()> { // Get the CLI matches let interface_name = matches.value_of("interface_name") - .ok_or_else(|| WgError::new("No 'interface_name' provided"))?; + .ok_or_else(|| "No 'interface_name' provided")?; // Create a `WireGuard` instance let wireguard = WireGuard::new(interface_name)?; diff --git a/tests/error.rs b/tests/error.rs index 67176db..e7fd9c5 100644 --- a/tests/error.rs +++ b/tests/error.rs @@ -1,7 +1,7 @@ extern crate wireguard; -use wireguard::WgError; -use std::error::Error; +use wireguard::error::*; +use std::error::Error as StdError; use std::fmt::Write; use std::io; @@ -10,14 +10,13 @@ static TEST_STR: &'static str = "Some error message"; #[test] fn success_convert_wg_from_io_error() { let io_error = io::Error::new(io::ErrorKind::NotFound, TEST_STR); - let wg_error: WgError = io_error.into(); + let wg_error: Error = io_error.into(); assert_eq!(wg_error.description(), TEST_STR.to_string()); - assert_eq!(wg_error.kind(), io::ErrorKind::Other); } #[test] fn success_convert_io_from_wg_error() { - let wg_error = WgError::new(TEST_STR); + let wg_error = Error::from(TEST_STR); let io_error: io::Error = wg_error.into(); assert_eq!(io_error.description(), TEST_STR.to_string()); assert_eq!(io_error.kind(), io::ErrorKind::Other); @@ -25,13 +24,13 @@ fn success_convert_io_from_wg_error() { #[test] fn success_wg_error_display_debug() { - let error = WgError::new(TEST_STR); + let error = Error::from(TEST_STR); let mut string = String::new(); write!(string, "{}", error).unwrap(); assert_eq!(string, TEST_STR); string.clear(); + // compiles write!(string, "{:?}", error).unwrap(); - assert_eq!(string, TEST_STR); } -- cgit v1.2.3-59-g8ed1b