Skip to content

Commit

Permalink
Stop printing Error::source in Display by default and add docs
Browse files Browse the repository at this point in the history
The `ParseEnv` error did print the source, while the `Deserialization`
one did not. I made this more consistent by not printing it at all,
unless the alternate flag is set -> then the sources are printed. Also
see https://stackoverflow.com/q/62869360/2408867
  • Loading branch information
LukasKalbertodt committed Oct 17, 2024
1 parent c11c8ba commit d454f09
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
6 changes: 2 additions & 4 deletions examples/parse_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,12 @@ fn parse_formats(input: &str) -> Result<Vec<Format>, Infallible> {
Ok(result)
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() {
std::env::set_var("PATHS", "/bin/ls,/usr/local/bin,/usr/bin/ls");
std::env::set_var("PORTS", "8080,8888,8000");
std::env::set_var("NAMES", "Alex|Peter|Mary");
std::env::set_var("TIMEOUT", "100");
std::env::set_var("FORMATS", "json5,yaml;.env");

println!("{:#?}", Conf::builder().env().load()?);

Ok(())
println!("{:#?}", Conf::builder().env().load());
}
11 changes: 6 additions & 5 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ struct LogConfig {
}


fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() {
let r = Conf::builder()
.env()
.file("examples/files/simple.toml")
.file("examples/files/etc/simple.yaml")
.load()?;
.load();

println!("{:#?}", r);

Ok(())
match r {
Ok(conf) => println!("{:#?}", conf),
Err(e) => println!("{e:#}"),
}
}
33 changes: 28 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ use std::path::PathBuf;


/// Type describing all errors that can occur in this library.
///
/// *Note*: the `Display` and `Debug` impls of this type do not include
/// information about `Error::source` by default. When showing this error to
/// end users, you should traverse the `source`-chain and print each error.
/// Crates like `anyhow` and `eyre` do this for you. As a convenience feature,
/// you can use the "alternate" flag `#` when printing this error to include
/// the source, e.g. `println!("{:#}", err)`. This will only print the direct
/// source though, so a proper traversal is still preferred!
pub struct Error {
pub(crate) inner: Box<ErrorInner>,
}
Expand Down Expand Up @@ -101,11 +109,21 @@ impl fmt::Display for Error {
ErrorInner::Io { path: None, .. } => {
std::write!(f, "IO error occured while loading configuration")
}
ErrorInner::Deserialization { source: Some(source), .. } => {
std::write!(f, "failed to deserialize configuration from {source}")
ErrorInner::Deserialization { source: Some(source), err } => {
std::write!(f, "failed to deserialize configuration from {source}")?;
if f.alternate() {
f.write_str(": ")?;
fmt::Display::fmt(&err, f)?;
}
Ok(())
}
ErrorInner::Deserialization { source: None, .. } => {
std::write!(f, "failed to deserialize configuration")
ErrorInner::Deserialization { source: None, err } => {
std::write!(f, "failed to deserialize configuration")?;
if f.alternate() {
f.write_str(": ")?;
fmt::Display::fmt(&err, f)?;
}
Ok(())
}
ErrorInner::EnvNotUnicode { field, key } => {
std::write!(f, "failed to load value `{field}` from \
Expand All @@ -117,7 +135,12 @@ impl fmt::Display for Error {
}
ErrorInner::EnvParseError { field, key, err } => {
std::write!(f, "failed to parse environment variable `{key}` into \
field `{field}`: {err}")
field `{field}`")?;
if f.alternate() {
f.write_str(": ")?;
fmt::Display::fmt(&err, f)?;
}
Ok(())
}
ErrorInner::UnsupportedFileFormat { path } => {
std::write!(f,
Expand Down

0 comments on commit d454f09

Please sign in to comment.