Merge pull request #807 from epage/error

fix(cli): Add path to filesystem errors
This commit is contained in:
Ed Page 2023-08-18 16:47:50 -05:00 committed by GitHub
commit ed607fcc7d
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 15 deletions

View file

@ -31,7 +31,13 @@ impl Config {
} }
pub fn from_file(path: &std::path::Path) -> Result<Self, anyhow::Error> { pub fn from_file(path: &std::path::Path) -> Result<Self, anyhow::Error> {
let s = std::fs::read_to_string(path)?; let s = std::fs::read_to_string(path).map_err(|err| {
let kind = err.kind();
std::io::Error::new(
kind,
format!("could not read config at `{}`", path.display()),
)
})?;
Self::from_toml(&s) Self::from_toml(&s)
} }

View file

@ -431,10 +431,14 @@ fn read_file(
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> { ) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
let buffer = if path == std::path::Path::new("-") { let buffer = if path == std::path::Path::new("-") {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
report_result(std::io::stdin().read_to_end(&mut buffer), reporter)?; report_result(
std::io::stdin().read_to_end(&mut buffer),
Some(path),
reporter,
)?;
buffer buffer
} else { } else {
report_result(std::fs::read(path), reporter)? report_result(std::fs::read(path), Some(path), reporter)?
}; };
let content_type = content_inspector::inspect(&buffer); let content_type = content_inspector::inspect(&buffer);
@ -460,7 +464,7 @@ fn read_file(
encoding_rs::DecoderResult::InputEmpty => Ok(decoded), encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
_ => Err(format!("invalid UTF-16LE encoding at byte {} in {}", written, path.display())), _ => Err(format!("invalid UTF-16LE encoding at byte {} in {}", written, path.display())),
}; };
let buffer = report_result(decoded, reporter)?; let buffer = report_result(decoded, Some(path), reporter)?;
(buffer.into_bytes(), content_type) (buffer.into_bytes(), content_type)
} }
content_inspector::ContentType::UTF_16BE => { content_inspector::ContentType::UTF_16BE => {
@ -473,7 +477,7 @@ fn read_file(
encoding_rs::DecoderResult::InputEmpty => Ok(decoded), encoding_rs::DecoderResult::InputEmpty => Ok(decoded),
_ => Err(format!("invalid UTF-16BE encoding at byte {} in {}", written, path.display())), _ => Err(format!("invalid UTF-16BE encoding at byte {} in {}", written, path.display())),
}; };
let buffer = report_result(decoded, reporter)?; let buffer = report_result(decoded, Some(path), reporter)?;
(buffer.into_bytes(), content_type) (buffer.into_bytes(), content_type)
}, },
}; };
@ -496,7 +500,7 @@ fn write_file(
| content_inspector::ContentType::UTF_8 | content_inspector::ContentType::UTF_8
| content_inspector::ContentType::UTF_8_BOM => buffer, | content_inspector::ContentType::UTF_8_BOM => buffer,
content_inspector::ContentType::UTF_16LE => { content_inspector::ContentType::UTF_16LE => {
let buffer = report_result(String::from_utf8(buffer), reporter)?; let buffer = report_result(String::from_utf8(buffer), Some(path), reporter)?;
if buffer.is_empty() { if buffer.is_empty() {
// Error occurred, don't clear out the file // Error occurred, don't clear out the file
return Ok(()); return Ok(());
@ -509,7 +513,7 @@ fn write_file(
encoded.into_owned() encoded.into_owned()
} }
content_inspector::ContentType::UTF_16BE => { content_inspector::ContentType::UTF_16BE => {
let buffer = report_result(String::from_utf8(buffer), reporter)?; let buffer = report_result(String::from_utf8(buffer), Some(path), reporter)?;
if buffer.is_empty() { if buffer.is_empty() {
// Error occurred, don't clear out the file // Error occurred, don't clear out the file
return Ok(()); return Ok(());
@ -524,9 +528,9 @@ fn write_file(
}; };
if path == std::path::Path::new("-") { if path == std::path::Path::new("-") {
report_result(std::io::stdout().write_all(&buffer), reporter)?; report_result(std::io::stdout().write_all(&buffer), Some(path), reporter)?;
} else { } else {
report_result(std::fs::write(path, buffer), reporter)?; report_result(std::fs::write(path, buffer), Some(path), reporter)?;
} }
Ok(()) Ok(())
@ -547,20 +551,26 @@ fn check_bytes<'a>(
fn report_result<T: Default, E: ToString>( fn report_result<T: Default, E: ToString>(
value: Result<T, E>, value: Result<T, E>,
path: Option<&std::path::Path>,
reporter: &dyn report::Report, reporter: &dyn report::Report,
) -> Result<T, std::io::Error> { ) -> Result<T, std::io::Error> {
let buffer = match value { let buffer = match value {
Ok(value) => value, Ok(value) => value,
Err(err) => { Err(err) => {
report_error(err, reporter)?; report_error(err, path, reporter)?;
Default::default() Default::default()
} }
}; };
Ok(buffer) Ok(buffer)
} }
fn report_error<E: ToString>(err: E, reporter: &dyn report::Report) -> Result<(), std::io::Error> { fn report_error<E: ToString>(
let msg = report::Error::new(err.to_string()); err: E,
path: Option<&std::path::Path>,
reporter: &dyn report::Report,
) -> Result<(), std::io::Error> {
let mut msg = report::Error::new(err.to_string());
msg.context = path.map(|path| report::Context::Path(report::PathContext { path }));
reporter.report(msg.into())?; reporter.report(msg.into())?;
Ok(()) Ok(())
} }
@ -672,7 +682,7 @@ fn walk_entry(
let entry = match entry { let entry = match entry {
Ok(entry) => entry, Ok(entry) => entry,
Err(err) => { Err(err) => {
report_error(err, reporter)?; report_error(err, None, reporter)?;
return Ok(()); return Ok(());
} }
}; };
@ -686,10 +696,15 @@ fn walk_entry(
let explicit = entry.depth() == 0; let explicit = entry.depth() == 0;
let (path, lookup_path) = if entry.is_stdin() { let (path, lookup_path) = if entry.is_stdin() {
let path = std::path::Path::new("-"); let path = std::path::Path::new("-");
(path, std::env::current_dir()?) let cwd = std::env::current_dir().map_err(|err| {
let kind = err.kind();
std::io::Error::new(kind, "no current working directory".to_owned())
})?;
(path, cwd)
} else { } else {
let path = entry.path(); let path = entry.path();
(path, path.canonicalize()?) let abs_path = report_result(path.canonicalize(), Some(path), reporter)?;
(path, abs_path)
}; };
let policy = engine.policy(&lookup_path); let policy = engine.policy(&lookup_path);
checks.check_file(path, explicit, &policy, reporter)?; checks.check_file(path, explicit, &policy, reporter)?;

View file

@ -0,0 +1,8 @@
bin.name = "typos"
args = "--config foo.toml"
status.code = 78
stdin = ""
# stdout doesn't have stable order
stderr = """
could not read config at `foo.toml`
"""