From aeb51dcf43665741a3438360151a4424e9b243e0 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Tue, 12 Mar 2019 00:25:56 +0100 Subject: Started to add helpful messages for errors which could occur during archiving --- src/errors.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/errors.rs (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..c85d123 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,90 @@ +use failure::{Backtrace, Context, Fail}; +use std::fmt::{self, Debug, Display}; +use yansi::Color; + +/// Kinds of error which might happen during folder archive generation +#[derive(Clone, Debug, PartialEq, Eq, Fail)] +pub enum CompressionErrorKind { + #[fail(display = "Could not open file {}", path)] + OpenFileError { path: String }, + #[fail(display = "Could not create temporary file")] + CreateTemporaryFileError, + #[fail(display = "Could not create file {}", path)] + CreateFileError { path: String }, + #[fail(display = "Could not retrieve entity name from the given path. + This can either mean that the entity has non UTF-8 characters in its name, + or that its name ends with \"..\"")] + InvalidDirectoryName, + #[fail(display = "Failed to create the TAR archive: {}", message)] + TarBuildingError { message: String }, + #[fail(display = "Failed to create the GZIP archive")] + GZipBuildingError, + #[fail(display = "Failed to retrieve TAR content")] + TarContentError, + #[fail(display = "Failed to retrieve GZIP content")] + GZipContentError, +} + +pub fn print_chain(err: CompressionError) { + for cause in Fail::iter_causes(&err) { + println!( + "{} {}", + Color::Magenta.paint("Caused by:").to_string(), + cause + ); + } +} + +pub struct CompressionError { + inner: Context, +} + +impl CompressionError { + fn new(kind: CompressionErrorKind) -> CompressionError { + CompressionError { + inner: Context::new(kind), + } + } +} + +impl Fail for CompressionError { + fn cause(&self) -> Option<&Fail> { + self.inner.cause() + } + + fn backtrace(&self) -> Option<&Backtrace> { + self.inner.backtrace() + } +} + +impl Display for CompressionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +impl Debug for CompressionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl From> for CompressionError { + fn from(inner: Context) -> CompressionError { + CompressionError { inner } + } +} + +impl From for CompressionError { + fn from(kind: CompressionErrorKind) -> CompressionError { + CompressionError { + inner: Context::new(kind), + } + } +} + +impl From for CompressionError { + fn from(_: std::option::NoneError) -> CompressionError { + CompressionError::new(CompressionErrorKind::InvalidDirectoryName) + } +} -- cgit v1.2.3 From 67d771fc3a954ea439e77afac092c84c5489d074 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Tue, 12 Mar 2019 19:23:22 +0100 Subject: Added some error messages + reworked the print_error_chain method --- src/errors.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index c85d123..191d382 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,9 +1,9 @@ use failure::{Backtrace, Context, Fail}; use std::fmt::{self, Debug, Display}; -use yansi::Color; +use yansi::{Color, Paint}; /// Kinds of error which might happen during folder archive generation -#[derive(Clone, Debug, PartialEq, Eq, Fail)] +#[derive(Debug, Fail)] pub enum CompressionErrorKind { #[fail(display = "Could not open file {}", path)] OpenFileError { path: String }, @@ -17,21 +17,37 @@ pub enum CompressionErrorKind { InvalidDirectoryName, #[fail(display = "Failed to create the TAR archive: {}", message)] TarBuildingError { message: String }, - #[fail(display = "Failed to create the GZIP archive")] - GZipBuildingError, + #[fail(display = "Failed to create the GZIP archive: {}", message)] + GZipBuildingError { message: String }, #[fail(display = "Failed to retrieve TAR content")] TarContentError, #[fail(display = "Failed to retrieve GZIP content")] GZipContentError, } -pub fn print_chain(err: CompressionError) { +pub fn print_error_chain(err: CompressionError) { + println!( + "{error} {err}", + error = Paint::red("error:").bold(), + err = Paint::white(&err).bold() + ); + print_backtrace(&err); for cause in Fail::iter_causes(&err) { println!( "{} {}", - Color::Magenta.paint("Caused by:").to_string(), + Color::RGB(255, 192, 0).paint("caused by:").to_string(), cause ); + print_backtrace(cause); + } +} + +fn print_backtrace(err: &dyn Fail) { + if let Some(backtrace) = err.backtrace() { + let backtrace = backtrace.to_string(); + if backtrace != "" { + println!("{}", backtrace); + } } } -- cgit v1.2.3 From 122a949ec49f84a49e7a5bec657a93a65faadce1 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Tue, 12 Mar 2019 20:16:45 +0100 Subject: Better error messages for invalid path --- src/errors.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index 191d382..6781bc6 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -11,10 +11,10 @@ pub enum CompressionErrorKind { CreateTemporaryFileError, #[fail(display = "Could not create file {}", path)] CreateFileError { path: String }, - #[fail(display = "Could not retrieve entity name from the given path. - This can either mean that the entity has non UTF-8 characters in its name, - or that its name ends with \"..\"")] + #[fail(display = "Invalid path: directory name cannot end with \"..\"")] InvalidDirectoryName, + #[fail(display = "Directory name contains invalid UTF-8 characters")] + InvalidUTF8DirectoryName, #[fail(display = "Failed to create the TAR archive: {}", message)] TarBuildingError { message: String }, #[fail(display = "Failed to create the GZIP archive: {}", message)] @@ -56,7 +56,7 @@ pub struct CompressionError { } impl CompressionError { - fn new(kind: CompressionErrorKind) -> CompressionError { + pub fn new(kind: CompressionErrorKind) -> CompressionError { CompressionError { inner: Context::new(kind), } @@ -98,9 +98,3 @@ impl From for CompressionError { } } } - -impl From for CompressionError { - fn from(_: std::option::NoneError) -> CompressionError { - CompressionError::new(CompressionErrorKind::InvalidDirectoryName) - } -} -- cgit v1.2.3 From e516fd628216d5ddf3bd3a7b836b3d9b14e57ee3 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Mar 2019 00:31:55 +0100 Subject: Improved error message --- src/errors.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index 6781bc6..d78216f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -11,9 +11,9 @@ pub enum CompressionErrorKind { CreateTemporaryFileError, #[fail(display = "Could not create file {}", path)] CreateFileError { path: String }, - #[fail(display = "Invalid path: directory name cannot end with \"..\"")] + #[fail(display = "Invalid path: directory name terminates in \"..\"")] InvalidDirectoryName, - #[fail(display = "Directory name contains invalid UTF-8 characters")] + #[fail(display = "Invalid path: directory name contains invalid UTF-8 characters")] InvalidUTF8DirectoryName, #[fail(display = "Failed to create the TAR archive: {}", message)] TarBuildingError { message: String }, -- cgit v1.2.3 From ae9fe2829a85501334c28b5e3980529ed55198ad Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Mar 2019 00:44:30 +0100 Subject: Added some docs comments to errors.rs --- src/errors.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index d78216f..3fcda8f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,7 +2,7 @@ use failure::{Backtrace, Context, Fail}; use std::fmt::{self, Debug, Display}; use yansi::{Color, Paint}; -/// Kinds of error which might happen during folder archive generation +/// Kinds of errors which might happen during the generation of an archive #[derive(Debug, Fail)] pub enum CompressionErrorKind { #[fail(display = "Could not open file {}", path)] @@ -25,6 +25,8 @@ pub enum CompressionErrorKind { GZipContentError, } +/// Prints the full chain of error, up to the root cause. +/// If RUST_BACKTRACE is set to 1, also prints the backtrace for each error pub fn print_error_chain(err: CompressionError) { println!( "{error} {err}", @@ -42,6 +44,8 @@ pub fn print_error_chain(err: CompressionError) { } } +/// Prints the backtrace of an error +/// RUST_BACKTRACE needs to be set to 1 to display the backtrace fn print_backtrace(err: &dyn Fail) { if let Some(backtrace) = err.backtrace() { let backtrace = backtrace.to_string(); @@ -51,6 +55,7 @@ fn print_backtrace(err: &dyn Fail) { } } +/// Based on https://boats.gitlab.io/failure/error-errorkind.html pub struct CompressionError { inner: Context, } -- cgit v1.2.3 From 2723babb9b8ddef120dfeb9b671e18f1a46dfb96 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Mar 2019 18:08:49 +0100 Subject: Build tar in buffer instead of in tempfile --- src/errors.rs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index 3fcda8f..8cfedff 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -5,12 +5,6 @@ use yansi::{Color, Paint}; /// Kinds of errors which might happen during the generation of an archive #[derive(Debug, Fail)] pub enum CompressionErrorKind { - #[fail(display = "Could not open file {}", path)] - OpenFileError { path: String }, - #[fail(display = "Could not create temporary file")] - CreateTemporaryFileError, - #[fail(display = "Could not create file {}", path)] - CreateFileError { path: String }, #[fail(display = "Invalid path: directory name terminates in \"..\"")] InvalidDirectoryName, #[fail(display = "Invalid path: directory name contains invalid UTF-8 characters")] -- cgit v1.2.3 From 17ef61a126e81c9ecfd1ebdd89537e854a06cae6 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Mar 2019 19:30:54 +0100 Subject: Switched to standard Rust logging system --- src/errors.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index 8cfedff..a9b6c74 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,6 +1,5 @@ use failure::{Backtrace, Context, Fail}; use std::fmt::{self, Debug, Display}; -use yansi::{Color, Paint}; /// Kinds of errors which might happen during the generation of an archive #[derive(Debug, Fail)] @@ -22,18 +21,10 @@ pub enum CompressionErrorKind { /// Prints the full chain of error, up to the root cause. /// If RUST_BACKTRACE is set to 1, also prints the backtrace for each error pub fn print_error_chain(err: CompressionError) { - println!( - "{error} {err}", - error = Paint::red("error:").bold(), - err = Paint::white(&err).bold() - ); + log::error!("{}", &err); print_backtrace(&err); for cause in Fail::iter_causes(&err) { - println!( - "{} {}", - Color::RGB(255, 192, 0).paint("caused by:").to_string(), - cause - ); + log::error!("caused by: {}", cause); print_backtrace(cause); } } @@ -44,7 +35,7 @@ fn print_backtrace(err: &dyn Fail) { if let Some(backtrace) = err.backtrace() { let backtrace = backtrace.to_string(); if backtrace != "" { - println!("{}", backtrace); + log::error!("{}", backtrace); } } } -- cgit v1.2.3 From 5b5f599055fb6221936c0985f656d0c4b7b2cb23 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Tue, 19 Mar 2019 20:08:57 +0100 Subject: Added documentation for errors and removed useless errors --- src/errors.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/errors.rs') diff --git a/src/errors.rs b/src/errors.rs index a9b6c74..2aa5f58 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,18 +4,24 @@ use std::fmt::{self, Debug, Display}; /// Kinds of errors which might happen during the generation of an archive #[derive(Debug, Fail)] pub enum CompressionErrorKind { + /// This error will occur if the directory name could not be retrieved from the path + /// See https://doc.rust-lang.org/std/path/struct.Path.html#method.file_name #[fail(display = "Invalid path: directory name terminates in \"..\"")] InvalidDirectoryName, + /// This error will occur when trying to convert an OSString into a String, if the path + /// contains invalid UTF-8 characters + /// See https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_str #[fail(display = "Invalid path: directory name contains invalid UTF-8 characters")] InvalidUTF8DirectoryName, + /// This error might occur while building a TAR archive, or while writing the termination sections + /// See https://docs.rs/tar/0.4.22/tar/struct.Builder.html#method.append_dir_all + /// and https://docs.rs/tar/0.4.22/tar/struct.Builder.html#method.into_inner #[fail(display = "Failed to create the TAR archive: {}", message)] TarBuildingError { message: String }, + /// This error might occur while building a GZIP archive, or while writing the GZIP trailer + /// See https://docs.rs/libflate/0.1.21/libflate/gzip/struct.Encoder.html#method.finish #[fail(display = "Failed to create the GZIP archive: {}", message)] GZipBuildingError { message: String }, - #[fail(display = "Failed to retrieve TAR content")] - TarContentError, - #[fail(display = "Failed to retrieve GZIP content")] - GZipContentError, } /// Prints the full chain of error, up to the root cause. -- cgit v1.2.3