From 9a96133bc2f2b933d1b7fe83f65126ec6b46e741 Mon Sep 17 00:00:00 2001 From: Yureka Date: Tue, 8 Oct 2024 11:45:11 +0200 Subject: [PATCH] improve error messages --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 10 ++++++++-- src/netconf/error.rs | 40 +++++++++++--------------------------- src/netconf/mod.rs | 32 ++++-------------------------- src/netconf/xml.rs | 46 ++++++++++++++++++++++++++++---------------- 6 files changed, 54 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 374ce46..b2b2f7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,6 +354,7 @@ dependencies = [ "serde", "ssh2", "ssh2-config", + "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4f163bf..b630556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ quick-xml = { version = "0.36.0", features = ["serialize"] } serde = { version = "1.0", features = [ "derive" ] } ssh2 = "0.9" ssh2-config = "0.2" +thiserror = "1.0.64" [lib] name = "rucli" diff --git a/src/main.rs b/src/main.rs index 6508136..362484e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,7 +114,10 @@ fn main() { netconf_session.lock_configuration().unwrap(); - netconf_session.load_configuration(data).unwrap(); + if let Err(e) = netconf_session.load_configuration(data) { + eprintln!("Config load failed: {}", e); + std::process::exit(1); + } let diff_reply = netconf_session .diff_configuration("text".to_string()) @@ -139,7 +142,10 @@ fn main() { let _ = netconf_session.lock_configuration().unwrap(); - netconf_session.load_configuration(data).unwrap(); + if let Err(e) = netconf_session.load_configuration(data) { + eprintln!("Config load failed: {}", e); + std::process::exit(1); + } let diff_reply = netconf_session .diff_configuration("text".to_string()) diff --git a/src/netconf/error.rs b/src/netconf/error.rs index 50f29a4..4ca8beb 100644 --- a/src/netconf/error.rs +++ b/src/netconf/error.rs @@ -1,38 +1,20 @@ use super::xml::RPCError; use crate::netconf::RPCReplyCommand; -#[derive(Debug)] +#[derive(Debug, thiserror::Error)] pub enum NETCONFError { - IoError(std::io::Error), - XmlError(quick_xml::Error), - XmlDeError(quick_xml::DeError), + #[error("{0}")] + IoError(#[from] std::io::Error), + #[error("{0}")] + XmlError(#[from] quick_xml::Error), + #[error("{0}")] + XmlDeError(#[from] quick_xml::DeError), + #[error("Missing OK")] MissingOk, + #[error("Unexpected command: {0}")] UnexpectedCommand(RPCReplyCommand), - RpcError(RPCError), + #[error("{0}")] + RpcError(#[from] RPCError), } pub type NETCONFResult = Result; - -impl From for NETCONFError { - fn from(err: std::io::Error) -> Self { - NETCONFError::IoError(err) - } -} - -impl From for NETCONFError { - fn from(err: quick_xml::Error) -> Self { - NETCONFError::XmlError(err) - } -} - -impl From for NETCONFError { - fn from(err: quick_xml::DeError) -> Self { - NETCONFError::XmlDeError(err) - } -} - -impl From for NETCONFError { - fn from(err: RPCError) -> Self { - NETCONFError::RpcError(err) - } -} diff --git a/src/netconf/mod.rs b/src/netconf/mod.rs index e483f6b..50be10a 100644 --- a/src/netconf/mod.rs +++ b/src/netconf/mod.rs @@ -102,13 +102,7 @@ impl NETCONFClient { match result { RPCReplyCommand::RPCError(error) => { if error.error_severity == "warning" { - let mut msg = "Warning: ".to_string(); - if let Some(error_path) = error.error_path { - msg.push_str(&error_path); - msg.push_str(&" "); - } - msg.push_str(&error.error_message); - eprintln!("{}", msg); + eprintln!("{}", error); } else { return Err(error.into()); } @@ -172,13 +166,7 @@ impl NETCONFClient { match result { RPCReplyCommand::RPCError(error) => { if error.error_severity == "warning" { - let mut msg = "Warning: ".to_string(); - if let Some(error_path) = error.error_path { - msg.push_str(&error_path); - msg.push_str(&" "); - } - msg.push_str(&error.error_message); - eprintln!("{}", msg); + eprintln!("{}", error); } else { return Err(error.into()); } @@ -201,13 +189,7 @@ impl NETCONFClient { match result { RPCReplyCommand::RPCError(error) => { if error.error_severity == "warning" { - let mut msg = "Warning: ".to_string(); - if let Some(error_path) = error.error_path { - msg.push_str(&error_path); - msg.push_str(&" "); - } - msg.push_str(&error.error_message); - eprintln!("{}", msg); + eprintln!("{}", error); } else { return Err(error.into()); } @@ -246,13 +228,7 @@ impl NETCONFClient { match result { LoadConfigurationResultsEnum::RPCError(error) => { if error.error_severity == "warning" { - let mut msg = "Warning: ".to_string(); - if let Some(error_path) = error.error_path { - msg.push_str(&error_path); - msg.push_str(&" "); - } - msg.push_str(&error.error_message); - eprintln!("{}", msg); + eprintln!("{}", error); } else { return Err(error.into()); } diff --git a/src/netconf/xml.rs b/src/netconf/xml.rs index a1d99ff..cb585d6 100644 --- a/src/netconf/xml.rs +++ b/src/netconf/xml.rs @@ -190,21 +190,20 @@ impl Display for RPCReplyCommand { } } -#[derive(Debug, Deserialize, Serialize)] - -pub struct RPCErrorList { - element: Vec, -} - #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct RPCError { #[serde(rename = "error-severity")] pub error_severity: String, - #[serde(rename = "error-path")] - pub error_path: Option, #[serde(rename = "error-message")] pub error_message: String, + + #[serde(rename = "error-path")] + pub error_path: Option, + #[serde(rename = "error-type")] + pub error_type: Option, + #[serde(rename = "error-tag")] + pub error_tag: Option, #[serde(rename = "error-info")] pub error_info: Option, #[serde(rename = "source-daemon")] @@ -215,21 +214,34 @@ pub struct RPCError { #[serde(deny_unknown_fields)] pub struct RPCErrorInfo { #[serde(rename = "bad-element")] - pub bad_element: Option, + pub bad_element: String, } impl Display for RPCError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!( + write!( f, - "{} at {:?} {:?}", - self.error_severity, - self.error_path, - self.error_info - .as_ref() - .map(|error_info| &error_info.bad_element) + "{}", + self.error_severity )?; - writeln!(f, "{}", self.error_message)?; + if let Some(error_path) = &self.error_path { + write!( + f, + " {}", + error_path + )?; + } + write!(f, ": {}", self.error_message)?; + if let Some(error_info) = &self.error_info { + write!( + f, + " (bad element: {})", + error_info.bad_element + )?; + } + write!(f, "")?; Ok(()) } } + +impl std::error::Error for RPCError { }