Skip to content

Commit

Permalink
Provide a better error on invalid filename or missing directory
Browse files Browse the repository at this point in the history
Closes #530.
  • Loading branch information
str4d committed Nov 3, 2024
1 parent 1d2b3bf commit ae5a392
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
4 changes: 4 additions & 0 deletions age/i18n/en-US/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ rec-deny-binary-output = Did you mean to use {-flag-armor}? {rec-detected-binary
err-deny-overwrite-file = refusing to overwrite existing file '{$filename}'.
err-invalid-filename = invalid filename '{$filename}'.
err-missing-directory = directory '{$path}' does not exist.
## Identity file errors

err-failed-to-write-output = Failed to write to output: {$err}
Expand Down
27 changes: 26 additions & 1 deletion age/src/cli_common/file_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ enum FileError {
DenyBinaryOutput,
DenyOverwriteFile(String),
DetectedBinaryOutput,
InvalidFilename(String),
MissingDirectory(String),
}

impl fmt::Display for FileError {
Expand All @@ -36,6 +38,10 @@ impl fmt::Display for FileError {
wlnfl!(f, "err-detected-binary")?;
wfl!(f, "rec-detected-binary")

Check warning on line 39 in age/src/cli_common/file_io.rs

View check run for this annotation

Codecov / codecov/patch

age/src/cli_common/file_io.rs#L38-L39

Added lines #L38 - L39 were not covered by tests
}
Self::InvalidFilename(filename) => {
wfl!(f, "err-invalid-filename", filename = filename.as_str())
}
Self::MissingDirectory(path) => wfl!(f, "err-missing-directory", path = path.as_str()),
}
}
}
Expand Down Expand Up @@ -345,10 +351,29 @@ impl OutputWriter {
// Respect the Unix convention that "-" as an output filename
// parameter is an explicit request to use standard output.
if filename != "-" {
let file_path = Path::new(&filename);

// Provide a better error if the filename is invalid, or the directory
// containing the file does not exist (we don't automatically create
// directories).
if let Some(dir_path) = file_path.parent() {
if !(dir_path == Path::new("") || dir_path.exists()) {
return Err(io::Error::new(
io::ErrorKind::NotFound,
FileError::MissingDirectory(dir_path.display().to_string()),
));
}
} else {
return Err(io::Error::new(
io::ErrorKind::NotFound,
FileError::InvalidFilename(filename),
));
}

// We open the file lazily, but as we don't want the caller to assume
// this, we eagerly confirm that the file does not exist if we can't
// overwrite it.
if !allow_overwrite && Path::new(&filename).exists() {
if !allow_overwrite && file_path.exists() {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
FileError::DenyOverwriteFile(filename),
Expand Down
10 changes: 10 additions & 0 deletions rage/tests/cmd/rage-keygen/gen-output-invalid-filename.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bin.name = "rage-keygen"
args = "-o ''"
status = "failed"
stdout = ""
stderr = """
Error: Failed to open output: invalid filename ''.
[ Did rage not do what you expected? Could an error be more useful? ]
[ Tell us: https://str4d.xyz/rage/report ]
"""
10 changes: 10 additions & 0 deletions rage/tests/cmd/rage-keygen/gen-output-missing-directory.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bin.name = "rage-keygen"
args = "-o does-not-exist/key.txt"
status = "failed"
stdout = ""
stderr = """
Error: Failed to open output: directory 'does-not-exist' does not exist.
[ Did rage not do what you expected? Could an error be more useful? ]
[ Tell us: https://str4d.xyz/rage/report ]
"""

0 comments on commit ae5a392

Please sign in to comment.