diff --git a/src/guide.md b/src/guide.md index 3ff6543d..632cd2fd 100644 --- a/src/guide.md +++ b/src/guide.md @@ -1,5 +1,10 @@ # SNAFU user's guide +Looking for quick help or answers? Please see the +[troubleshooting](guide::troubleshooting) page. + +--- + Once you've got a high-level idea of what SNAFU can do by looking at the [quick example](crate) and some [more examples](guide::examples), take a peek at [our design philosophy](guide::philosophy). diff --git a/src/guide/troubleshooting.md b/src/guide/troubleshooting.md new file mode 100644 index 00000000..60538c50 --- /dev/null +++ b/src/guide/troubleshooting.md @@ -0,0 +1,18 @@ +# Troubleshooting common issues + +This section covers some commonly asked and encountered questions. If +you experience a problem and spend a significant amount of time +answering it, please consider [submitting a pull request][pr] to add +it here. If you cannot solve your issue after reading this, please +[open an issue][issue] to ask your question. + +[pr]: https://github.com/shepmaster/snafu/blob/master/CONTRIBUTING.md +[issue]: https://github.com/shepmaster/snafu/issues + +## `missing field 'source' in initializer` + +Do you have errors talking about the source field missing, +`snafu::IntoError<_>` not being satisfied, and your project is +multiple modules or files? + +[**answers**](troubleshooting::missing_field_source) diff --git a/src/guide/troubleshooting/missing_field_source.md b/src/guide/troubleshooting/missing_field_source.md new file mode 100644 index 00000000..5e0a9cc2 --- /dev/null +++ b/src/guide/troubleshooting/missing_field_source.md @@ -0,0 +1,99 @@ +# Missing field source / IntoError is not implemented + +This error is encountered in multi-module / multi-file projects when +the error type is defined in one module and constructed in another. + +## Failing Example + +**project_error.rs** + +```rust,ignore +use snafu::Snafu; +use std::io; + +#[derive(Debug, Snafu)] +#[snafu(visibility(pub(crate)))] +pub enum ProjectError { + #[snafu(visibility(pub(crate)))] + #[snafu(display("Unable to read configuration from {}: {}", path, source))] + IOConfigError { + path: &'static str, + source: io::Error, + }, +} +``` + +**main.rs** + +```rust,ignore +mod project_error; + +use project_error::ProjectError; +use snafu::ResultExt; +use std::{fs, io}; + +const CONFIG_PATH: &str = "/etc/example/conf.conf"; + +pub fn read_config() -> Result { + fs::read_to_string(CONFIG_PATH).context(ProjectError::IOConfigError { path: CONFIG_PATH }) +} + +pub fn main() { + println!("{}", read_config().unwrap()); +} +``` + +## Errors + +```text +error[E0063]: missing field `source` in initializer of `project_error::ProjectError` + --> src/lib.rs:200:9 + | +27 | ProjectError::IOConfigError { path: CONFIG_PATH } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `source` +``` + +and + +```text +error[E0277]: the trait bound `project_error::ProjectError: snafu::IntoError<_>` is not satisfied + --> src/lib.rs:200:9 + | +27 | ProjectError::IOConfigError { path: CONFIG_PATH } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `snafu::IntoError<_>` is not implemented for `project_error::ProjectError` +the trait bound 'project_error::ProjectError: snafu::IntoError<_>' is not satisfied +``` + +## Solution + +Replace the `ProjectError::IOConfigError` in the `read_config()` +function with `project_error::IOConfigError`. + +## Explanation + +This works because the `#[derive(Snafu)]` macro creates the *context +selector* type `IoConfigError`: + +```rust,ignore +#[derive(Debug, Snafu)] +pub enum ProjectError { + IOConfigError { + source: io::Error, + path: &'static str, + }, +} + +// some details removed +struct IOConfigError

{ + path: P, +} + +// Some impls for the IOConfigError struct +``` + +See [the macro section](guide::the_macro) of the guide for more details. + +When you use `ProjectError::IOConfigError`, you're referencing the +enum variant, not the struct that you need. Replacing +`ProjectError::IOConfigError` with `project_error::IOConfigError` +fixes this problem. diff --git a/src/lib.rs b/src/lib.rs index 415ebb28..c4634126 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -159,6 +159,9 @@ generate_guide! { pub mod philosophy; pub mod structs; pub mod the_macro; + pub mod troubleshooting { + pub mod missing_field_source; + } pub mod upgrading; @code pub mod examples;