Skip to content

Commit

Permalink
fix!: improve password-command error reporting (#265)
Browse files Browse the repository at this point in the history
* When process spawning failed, e.g. command did not exist, then
previously the only output was "error: No such file or directory"
without any context about what Rustic was trying to do. This is changed.
* Also when `wait_with_output()` failed, the detailed error was not
reported.
* Renamed error kind `PasswordCommandParsingFailed` to
`PasswordCommandExecutionFailed` because the error conditions had
nothing to do with parsing. (Also updated `rustic`:
rustic-rs/rustic#1237)
  • Loading branch information
intgr authored Sep 13, 2024
1 parent 2d52c09 commit 8ef75e6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
4 changes: 2 additions & 2 deletions crates/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ pub enum RepositoryErrorKind {
IsNotHotRepository,
/// incorrect password!
IncorrectPassword,
/// failed to call password command
PasswordCommandParsingFailed,
/// error running the password command
PasswordCommandExecutionFailed,
/// error reading password from command
ReadingPasswordFromCommandFailed,
/// error listing the repo config file
Expand Down
38 changes: 26 additions & 12 deletions crates/core/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl RepositoryOptions {
/// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed
/// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed
/// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed
/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::PasswordCommandExecutionFailed`] - If executing the password command failed
/// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed
///
/// # Returns
Expand All @@ -185,7 +185,7 @@ impl RepositoryOptions {
/// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: crate::error::RepositoryErrorKind::OpeningPasswordFileFailed
/// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed
/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError
/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed
/// [`RepositoryErrorKind::PasswordCommandExecutionFailed`]: crate::error::RepositoryErrorKind::PasswordCommandExecutionFailed
/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed
pub fn evaluate_password(&self) -> RusticResult<Option<String>> {
match (&self.password, &self.password_file, &self.password_command) {
Expand All @@ -201,18 +201,32 @@ impl RepositoryOptions {
let command = Command::new(&command[0])
.args(&command[1..])
.stdout(Stdio::piped())
.spawn()?;
let Ok(output) = command.wait_with_output() else {
return Err(RepositoryErrorKind::PasswordCommandParsingFailed.into());
.spawn();

let process = match command {
Ok(process) => process,
Err(err) => {
error!("password-command could not be executed: {}", err);
return Err(RepositoryErrorKind::PasswordCommandExecutionFailed.into());
}
};

let output = match process.wait_with_output() {
Ok(output) => output,
Err(err) => {
error!("error reading output from password-command: {}", err);
return Err(RepositoryErrorKind::ReadingPasswordFromCommandFailed.into());
}
};

if !output.status.success() {
#[allow(clippy::option_if_let_else)]
let s = match output.status.code() {
Some(c) => format!("exited with status code {c}"),
None => "was terminated".into(),
};
error!("password-command {s}");
return Err(RepositoryErrorKind::ReadingPasswordFromCommandFailed.into());
return Err(RepositoryErrorKind::PasswordCommandExecutionFailed.into());
}

let mut pwd = BufReader::new(&*output.stdout);
Expand Down Expand Up @@ -376,7 +390,7 @@ impl<P, S> Repository<P, S> {
/// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed
/// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed
/// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed
/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::PasswordCommandExecutionFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed
///
/// # Returns
Expand All @@ -386,7 +400,7 @@ impl<P, S> Repository<P, S> {
/// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: crate::error::RepositoryErrorKind::OpeningPasswordFileFailed
/// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed
/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError
/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed
/// [`RepositoryErrorKind::PasswordCommandExecutionFailed`]: crate::error::RepositoryErrorKind::PasswordCommandExecutionFailed
/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed
pub fn password(&self) -> RusticResult<Option<String>> {
self.opts.evaluate_password()
Expand Down Expand Up @@ -427,7 +441,7 @@ impl<P, S> Repository<P, S> {
/// * [`RepositoryErrorKind::NoPasswordGiven`] - If no password is given
/// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed
/// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed
/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::PasswordCommandExecutionFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed
/// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed
/// * [`RepositoryErrorKind::NoRepositoryConfigFound`] - If no repository config file is found
Expand All @@ -444,7 +458,7 @@ impl<P, S> Repository<P, S> {
/// [`RepositoryErrorKind::NoPasswordGiven`]: crate::error::RepositoryErrorKind::NoPasswordGiven
/// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed
/// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: crate::error::RepositoryErrorKind::OpeningPasswordFileFailed
/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed
/// [`RepositoryErrorKind::PasswordCommandExecutionFailed`]: crate::error::RepositoryErrorKind::PasswordCommandExecutionFailed
/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed
/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError
/// [`RepositoryErrorKind::NoRepositoryConfigFound`]: crate::error::RepositoryErrorKind::NoRepositoryConfigFound
Expand Down Expand Up @@ -537,14 +551,14 @@ impl<P, S> Repository<P, S> {
/// * [`RepositoryErrorKind::NoPasswordGiven`] - If no password is given
/// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed
/// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed
/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::PasswordCommandExecutionFailed`] - If parsing the password command failed
/// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed
/// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed
///
/// [`RepositoryErrorKind::NoPasswordGiven`]: crate::error::RepositoryErrorKind::NoPasswordGiven
/// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed
/// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: crate::error::RepositoryErrorKind::OpeningPasswordFileFailed
/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed
/// [`RepositoryErrorKind::PasswordCommandExecutionFailed`]: crate::error::RepositoryErrorKind::PasswordCommandExecutionFailed
/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed
/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError
pub fn init(
Expand Down

0 comments on commit 8ef75e6

Please sign in to comment.