Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Commonly Asked Questions page in guide. #266

Merged
merged 1 commit into from
Jan 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/guide.md
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
18 changes: 18 additions & 0 deletions src/guide/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -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)
99 changes: 99 additions & 0 deletions src/guide/troubleshooting/missing_field_source.md
Original file line number Diff line number Diff line change
@@ -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<String, ProjectError> {
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<P> {
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.
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down