Browse Source

try using thiserror

thiserror
Robey 6 months ago
parent
commit
87c8bd3d69
  1. 1
      Cargo.lock
  2. 1
      Cargo.toml
  3. 2
      src/asymmetric.rs
  4. 177
      src/bottle_error.rs

1
Cargo.lock

@ -221,6 +221,7 @@ dependencies = [
"sha2",
"snap",
"term_size",
"thiserror",
"users",
]

1
Cargo.toml

@ -52,4 +52,5 @@ rust-lzma = "0.5.1"
sha2 = "0.9.5"
snap = "1.0.5"
term_size = "0.3.2"
thiserror = "1.0.26"
users = "0.11.0"

2
src/asymmetric.rs

@ -266,7 +266,7 @@ impl Ed25519SecretKey {
String::from_utf8(kdf_name.to_vec()).unwrap_or_else(|_| "?".to_string()),
String::from_utf8(cipher_name.to_vec()).unwrap_or_else(|_| "?".to_string()),
);
return Err(BottleError::UnsupportedSshFileEncryption(filename.to_string(), kind));
return Err(BottleError::UnsupportedSshFileEncryption { filename: filename.to_string(), kind });
}
};

177
src/bottle_error.rs

@ -1,57 +1,135 @@
use lzma::LzmaError;
use std::error::Error;
use std::fmt;
use std::path::PathBuf;
use thiserror::Error;
use crate::bottle_cap::BottleType;
/// std::io::Error is too annoying
#[derive(Debug)]
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum BottleError {
IoError(std::io::Error),
#[error("I/O error: {:?}{}",
.0.kind(),
.0.get_ref().map(|inner| format!(": {}", inner)).unwrap_or_else(|| "".to_string())
)]
IoError(#[from] std::io::Error),
#[error("{0}: {1:?}")]
FileError(String, std::io::ErrorKind),
#[error("Bad magic number")]
BadMagic,
#[error("Unknown bottle version")]
UnknownVersion,
#[error("Unknown bottle type")]
UnknownBottleType,
#[error("Bottle header too large")]
HeaderTooLarge,
#[error("Bad CRC32C: got {got:x}, expected {expected:x}")]
BadCrc { expected: u32, got: u32 },
#[error("Corrupt stream (bad signal)")]
CorruptStream,
#[error("Internal error: previous stream was not closed")]
InvalidBottleState,
#[error("Wrong bottle type: got {got:?}, expected {expected:?}")]
WrongBottleType { expected: BottleType, got: BottleType },
#[error("Corrupt bottle: incorrect stream type(s) for bottle")]
WrongStreamType,
#[error("Extra stream in bottle")]
UnexpectedStream,
#[error("Bottle is missing a mandatory header")]
MissingHeader,
NoStream, // internal error
// signatures:
#[error("Internal error: No stream has been opened in this bottle")]
NoStream,
// ----- signatures:
#[error("Not an Ed25519 key")]
NotAnEd25519Key,
#[error("Error decoding ssh key format")]
SshEncodingError,
#[error("Not an ssh key file: {0}")]
InvalidSshFile(String),
UnsupportedSshFileEncryption(String, String),
#[error("Unsupported encryption ({kind}) in ssh file: {filename}")]
UnsupportedSshFileEncryption { filename: String, kind: String },
#[error("Password required for this SSH key file")]
SshPasswordRequired,
#[error("Error encrypting message with Ed25519 key material")]
DryocBoxError,
// compressed bottles:
// ----- compressed bottles:
#[error("Unknown compression")]
UnknownCompression,
#[error("Error compressing data")]
CompressionError, // probably an internal error in the compressor
#[error("LZMA error: {0}")]
Lzma2Error(LzmaError),
// encrypted bottles:
// ----- encrypted bottles:
#[error("No CPRNG random bytes available")]
NoRandom,
#[error("Unknown encryption")]
UnknownEncryption,
#[error("Bad key size for encryption algorithm")]
BadKeySize,
#[error("No key or password provided for encrypted bottle")]
RequiresKey,
#[error("Password provided but encrypted bottle is not password protected")]
NotPasswordEncrypted,
#[error("Internal error: Argon2 key generation error: {0}")]
Argon2Error(argonautica::Error), // probably an internal error
#[error("Public key in encrypted bottle is corrupted")]
CorruptPublicKey,
#[error("No public key that can decode this bottle (encrypted for: {})", .0.join(", "))]
NoMatchingPublicKey(Vec<String>),
#[error("Encryption engine failure (wrong password or key?)")]
CipherError,
// file bottles:
// ----- file bottles:
#[error("File archive is missing some blocks (corrupted)")]
IncompleteFileArchive,
#[error("Unknown hash type for file blocking")]
UnknownHashType,
#[error("Invalid path for adding to archive (contains . or ..): {0:?}")]
InvalidAddPath(PathBuf),
#[error("Invalid path (failed to parse: OS error?)")]
BadPath,
#[error("Paths would resolve to the same relative path in the archive: {0:?}, {1:?}")]
DuplicatePaths(PathBuf, PathBuf),
}
@ -61,81 +139,4 @@ impl BottleError {
}
}
impl Error for BottleError {
}
impl From<std::io::Error> for BottleError {
fn from(error: std::io::Error) -> BottleError {
BottleError::IoError(error)
}
}
impl fmt::Display for BottleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::IoError(e) => {
if let Some(inner) = e.get_ref() {
if e.kind() == std::io::ErrorKind::Other {
write!(f, "{}", inner)?
} else {
write!(f, "I/O error: {:?}: {}", e.kind(), inner)?
}
} else {
write!(f, "I/O error: {:?}", e.kind())?
}
},
Self::FileError(filename, e) => write!(f, "{}: {:?}", filename, e)?,
Self::BadMagic => write!(f, "Bad magic number")?,
Self::UnknownVersion => write!(f, "Unknown bottle version")?,
Self::UnknownBottleType => write!(f, "Unknown bottle type")?,
Self::HeaderTooLarge => write!(f, "Bottle header too large")?,
Self::BadCrc { expected, got } => write!(f, "Bad CRC32C: got {:x}, expected {:x}", got, expected)?,
Self::CorruptStream => write!(f, "Corrupt stream (bad signal)")?,
Self::InvalidBottleState => write!(f, "Internal error: previous stream was not closed")?,
Self::WrongBottleType { expected, got } => {
write!(f, "Wrong bottle type: got {:?}, expected {:?}", got, expected)?
},
Self::WrongStreamType => write!(f, "Corrupt bottle: incorrect stream type(s) for bottle")?,
Self::UnexpectedStream => write!(f, "Extra stream in bottle")?,
Self::MissingHeader => write!(f, "Bottle is missing a mandatory header")?,
Self::NoStream => write!(f, "No stream has been opened in this bottle")?,
Self::NotAnEd25519Key => write!(f, "Not an Ed25519 key")?,
Self::SshEncodingError => write!(f, "Error decoding ssh key format")?,
Self::InvalidSshFile(filename) => write!(f, "Not an ssh key file: {}", filename)?,
Self::UnsupportedSshFileEncryption(filename, kind) => {
write!(f, "Unsupported encryption ({}) in ssh file: {}", kind, filename)?
},
Self::SshPasswordRequired => write!(f, "Password required for this SSH key file")?,
Self::DryocBoxError => write!(f, "Error encrypting message with Ed25519 key material")?,
Self::UnknownCompression => write!(f, "Unknown compression")?,
Self::CompressionError => write!(f, "Error compressing data")?,
Self::Lzma2Error(e) => write!(f, "LZMA error: {}", e)?,
Self::NoRandom => write!(f, "No CPRNG random bytes available")?,
Self::UnknownEncryption => write!(f, "Unknown encryption")?,
Self::BadKeySize => write!(f, "Bad key size for encryption algorithm")?,
Self::RequiresKey => write!(f, "No key or password provided for encrypted bottle")?,
Self::NotPasswordEncrypted => {
write!(f, "Password provided but encrypted bottle is not password protected")?
},
Self::Argon2Error(e) => write!(f, "Argon2 key generation error: {}", e)?,
Self::CorruptPublicKey => write!(f, "Public key in encrypted bottle is corrupted")?,
Self::NoMatchingPublicKey(names) => {
write!(f, "No public key that can decode this bottle (encrypted for: {})", names.join(", "))?
},
Self::CipherError => write!(f, "Encryption engine failure (wrong password or key?)")?,
Self::IncompleteFileArchive => write!(f, "File archive is missing some blocks (corrupted)")?,
Self::UnknownHashType => write!(f, "Unknown hash type for file blocking")?,
Self::InvalidAddPath(path) => {
write!(f, "Invalid path for adding to archive (contains . or ..): {:?}", path)?
},
Self::BadPath => write!(f, "Invalid path (failed to parse: OS error?)")?,
Self::DuplicatePaths(path1, path2) => {
write!(f, "Paths would resolve to the same relative path in the archive: {:?}, {:?}", path1, path2)?
},
};
Ok(())
}
}
pub type BottleResult<T> = Result<T, BottleError>;

Loading…
Cancel
Save