diff options
Diffstat (limited to 'src/errors.rs')
-rw-r--r-- | src/errors.rs | 144 |
1 files changed, 74 insertions, 70 deletions
diff --git a/src/errors.rs b/src/errors.rs index 21d9e07..bd6dc66 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,85 +1,82 @@ use failure::{Backtrace, Context, Fail}; use std::fmt::{self, Debug, Display}; -/// Kinds of errors which might happen during file upload #[derive(Debug, Fail)] -pub enum FileUploadErrorKind { - /// This error will occur when file overriding is off and a file with same name already exists - #[fail(display = "File with this name already exists")] - FileExist, - /// This error will occur when the server fails to process the HTTP header during file upload - #[fail(display = "Failed to parse incoming request")] - ParseError, - /// This error will occur when we fail to process the multipart request - #[fail(display = "Failed to process multipart request")] +pub enum ContextualErrorKind { + /// Fully customized errors, not inheriting from any error + #[fail(display = "{}", _0)] + CustomError(String), + + /// Any kind of IO errors + #[fail(display = "{}\ncaused by: {}", _0, _1)] + IOError(String, std::io::Error), + + /// MultipartError, which might occur during file upload, when processing the multipart request fails + #[fail(display = "Failed to process multipart request\ncaused by: {}", _0)] MultipartError(actix_web::error::MultipartError), - /// This error may occur when trying to write the incoming file to disk - #[fail(display = "Failed to create or write to file")] - IOError(std::io::Error), - /// This error will occur when we he have insuffictent permissions to create new file - #[fail(display = "Insufficient permissions to create file")] - InsufficientPermissions, -} -/// 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 }, -} + /// This error might occur when decoding the HTTP authentication header. + #[fail( + display = "Failed to decode HTTP authentication header\ncaused by: {}", + _0 + )] + Base64DecodeError(base64::DecodeError), -/// 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) { - log::error!("{}", &err); - print_backtrace(&err); - for cause in Fail::iter_causes(&err) { - log::error!("caused by: {}", cause); - print_backtrace(cause); - } + /// Any error related to an invalid path (failed to retrieve entry name, unexpected entry type, etc) + #[fail(display = "Invalid path\ncaused by: {}", _0)] + InvalidPathError(String), + + /// This error might occur if the HTTP credential string does not respect the expected format + #[fail(display = "Invalid format for credentials string. Expected is username:format")] + InvalidAuthFormat, + + /// This error might occur if the HTTP auth password exceeds 255 characters + #[fail(display = "HTTP password length exceeds 255 characters")] + PasswordTooLongError, + + /// This error might occur if the user has unsufficient permissions to create an entry in a given directory + #[fail(display = "Insufficient permissions to create file in {}", _0)] + InsufficientPermissionsError(String), + + /// Any error related to parsing. + #[fail(display = "Failed to parse {}\ncaused by: {}", _0, _1)] + ParseError(String, String), + + /// This error might occur when the creation of an archive fails + #[fail( + display = "An error occured while creating the {}\ncaused by: {}", + _0, _1 + )] + ArchiveCreationError(String, Box<ContextualError>), + + /// This error might occur when the HTTP authentication fails + #[fail( + display = "An error occured during HTTP authentication\ncaused by: {}", + _0 + )] + HTTPAuthenticationError(Box<ContextualError>), } -/// 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(); - if backtrace != "" { - log::error!("{}", backtrace); - } +pub fn log_error_chain(description: String) { + for cause in description.lines() { + log::error!("{}", cause); } } /// Based on https://boats.gitlab.io/failure/error-errorkind.html -pub struct CompressionError { - inner: Context<CompressionErrorKind>, +pub struct ContextualError { + inner: Context<ContextualErrorKind>, } -impl CompressionError { - pub fn new(kind: CompressionErrorKind) -> CompressionError { - CompressionError { +impl ContextualError { + pub fn new(kind: ContextualErrorKind) -> ContextualError { + ContextualError { inner: Context::new(kind), } } } -impl Fail for CompressionError { +impl Fail for ContextualError { fn cause(&self) -> Option<&Fail> { self.inner.cause() } @@ -89,28 +86,35 @@ impl Fail for CompressionError { } } -impl Display for CompressionError { +impl Display for ContextualError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.inner, f) } } -impl Debug for CompressionError { +impl Debug for ContextualError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Debug::fmt(&self.inner, f) } } -impl From<Context<CompressionErrorKind>> for CompressionError { - fn from(inner: Context<CompressionErrorKind>) -> CompressionError { - CompressionError { inner } +impl From<Context<ContextualErrorKind>> for ContextualError { + fn from(inner: Context<ContextualErrorKind>) -> ContextualError { + ContextualError { inner } } } -impl From<CompressionErrorKind> for CompressionError { - fn from(kind: CompressionErrorKind) -> CompressionError { - CompressionError { +impl From<ContextualErrorKind> for ContextualError { + fn from(kind: ContextualErrorKind) -> ContextualError { + ContextualError { inner: Context::new(kind), } } } + +/// This allows to create CustomErrors more simply +impl From<String> for ContextualError { + fn from(msg: String) -> ContextualError { + ContextualError::new(ContextualErrorKind::CustomError(msg)) + } +} |