mirror of https://github.com/zkat/miette.git
fix(docs): readme was getting cut off during generation
Fixes: https://github.com/zkat/miette/issues/174
This commit is contained in:
parent
e537ffa473
commit
e286c705fd
223
README.md
223
README.md
|
|
@ -383,6 +383,229 @@ pub struct MyErrorType {
|
||||||
##### ... help text
|
##### ... help text
|
||||||
`miette` provides two facilities for supplying help text for your errors:
|
`miette` provides two facilities for supplying help text for your errors:
|
||||||
|
|
||||||
|
The first is the `#[help()]` format attribute that applies to structs or
|
||||||
|
enum variants:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::Diagnostic;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Diagnostic, Error)]
|
||||||
|
#[error("welp")]
|
||||||
|
#[diagnostic(help("try doing this instead"))]
|
||||||
|
struct Foo;
|
||||||
|
```
|
||||||
|
|
||||||
|
The other is by programmatically supplying the help text as a field to
|
||||||
|
your diagnostic:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::Diagnostic;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Diagnostic, Error)]
|
||||||
|
#[error("welp")]
|
||||||
|
#[diagnostic()]
|
||||||
|
struct Foo {
|
||||||
|
#[help]
|
||||||
|
advice: Option<String>, // Can also just be `String`
|
||||||
|
}
|
||||||
|
|
||||||
|
let err = Foo {
|
||||||
|
advice: Some("try doing this instead".to_string()),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ... multiple related errors
|
||||||
|
|
||||||
|
`miette` supports collecting multiple errors into a single diagnostic, and
|
||||||
|
printing them all together nicely.
|
||||||
|
|
||||||
|
To do so, use the `#[related]` tag on any `IntoIter` field in your
|
||||||
|
`Diagnostic` type:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::Diagnostic;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
|
#[error("oops")]
|
||||||
|
struct MyError {
|
||||||
|
#[related]
|
||||||
|
others: Vec<MyError>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ... delayed source code
|
||||||
|
|
||||||
|
Sometimes it makes sense to add source code to the error message later.
|
||||||
|
One option is to use [`with_source_code()`](Report::with_source_code)
|
||||||
|
method for that:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::{Diagnostic, SourceSpan};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Diagnostic, Debug, Error)]
|
||||||
|
#[error("oops")]
|
||||||
|
#[diagnostic()]
|
||||||
|
pub struct MyErrorType {
|
||||||
|
// Note: label but no source code
|
||||||
|
#[label]
|
||||||
|
err_span: SourceSpan,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_something() -> miette::Result<()> {
|
||||||
|
// This function emits actual error with label
|
||||||
|
return Err(MyErrorType {
|
||||||
|
err_span: (7..11).into(),
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> miette::Result<()> {
|
||||||
|
do_something().map_err(|error| {
|
||||||
|
// And this code provides the source code for inner error
|
||||||
|
error.with_source_code(String::from("source code"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also source code can be provided by a wrapper type. This is especially
|
||||||
|
useful in combination with `related`, when multiple errors should be
|
||||||
|
emitted at the same time:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::{Diagnostic, Report, SourceSpan};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Diagnostic, Debug, Error)]
|
||||||
|
#[error("oops")]
|
||||||
|
#[diagnostic()]
|
||||||
|
pub struct InnerError {
|
||||||
|
// Note: label but no source code
|
||||||
|
#[label]
|
||||||
|
err_span: SourceSpan,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic, Debug, Error)]
|
||||||
|
#[error("oops: multiple errors")]
|
||||||
|
#[diagnostic()]
|
||||||
|
pub struct MultiError {
|
||||||
|
// Note source code by no labels
|
||||||
|
#[source_code]
|
||||||
|
source_code: String,
|
||||||
|
// The source code above is used for these errors
|
||||||
|
#[related]
|
||||||
|
related: Vec<InnerError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_something() -> Result<(), Vec<InnerError>> {
|
||||||
|
Err(vec![
|
||||||
|
InnerError {
|
||||||
|
err_span: (0..6).into(),
|
||||||
|
},
|
||||||
|
InnerError {
|
||||||
|
err_span: (7..11).into(),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> miette::Result<()> {
|
||||||
|
do_something().map_err(|err_list| MultiError {
|
||||||
|
source_code: "source code".into(),
|
||||||
|
related: err_list,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ... Diagnostic-based error sources.
|
||||||
|
|
||||||
|
When one uses the `#[source]` attribute on a field, that usually comes
|
||||||
|
from `thiserror`, and implements a method for
|
||||||
|
[`std::error::Error::source`]. This works in many cases, but it's lossy:
|
||||||
|
if the source of the diagnostic is a diagnostic itself, the source will
|
||||||
|
simply be treated as an `std::error::Error`.
|
||||||
|
|
||||||
|
While this has no effect on the existing _reporters_, since they don't use
|
||||||
|
that information right now, APIs who might want this information will have
|
||||||
|
no access to it.
|
||||||
|
|
||||||
|
If it's important for you for this information to be available to users,
|
||||||
|
you can use `#[diagnostic_source]` alongside `#[source]`. Not that you
|
||||||
|
will likely want to use _both_:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use miette::Diagnostic;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Diagnostic, Error)]
|
||||||
|
#[error("MyError")]
|
||||||
|
struct MyError {
|
||||||
|
#[source]
|
||||||
|
#[diagnostic_source]
|
||||||
|
the_cause: OtherError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Diagnostic, Error)]
|
||||||
|
#[error("OtherError")]
|
||||||
|
struct OtherError;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ... handler options
|
||||||
|
|
||||||
|
[`MietteHandler`] is the default handler, and is very customizable. In
|
||||||
|
most cases, you can simply use [`MietteHandlerOpts`] to tweak its behavior
|
||||||
|
instead of falling back to your own custom handler.
|
||||||
|
|
||||||
|
Usage is like so:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
miette::set_hook(Box::new(|_| {
|
||||||
|
Box::new(
|
||||||
|
miette::MietteHandlerOpts::new()
|
||||||
|
.terminal_links(true)
|
||||||
|
.unicode(false)
|
||||||
|
.context_lines(3)
|
||||||
|
.tab_width(4)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
See the docs for [`MietteHandlerOpts`] for more details on what you can
|
||||||
|
customize!
|
||||||
|
|
||||||
|
### Acknowledgements
|
||||||
|
|
||||||
|
`miette` was not developed in a void. It owes enormous credit to various
|
||||||
|
other projects and their authors:
|
||||||
|
|
||||||
|
- [`anyhow`](http://crates.io/crates/anyhow) and
|
||||||
|
[`color-eyre`](https://crates.io/crates/color-eyre): these two
|
||||||
|
enormously influential error handling libraries have pushed forward the
|
||||||
|
experience of application-level error handling and error reporting.
|
||||||
|
`miette`'s `Report` type is an attempt at a very very rough version of
|
||||||
|
their `Report` types.
|
||||||
|
- [`thiserror`](https://crates.io/crates/thiserror) for setting the
|
||||||
|
standard for library-level error definitions, and for being the
|
||||||
|
inspiration behind `miette`'s derive macro.
|
||||||
|
- `rustc` and [@estebank](https://github.com/estebank) for their
|
||||||
|
state-of-the-art work in compiler diagnostics.
|
||||||
|
- [`ariadne`](https://crates.io/crates/ariadne) for pushing forward how
|
||||||
|
_pretty_ these diagnostics can really look!
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
`miette` is released to the Rust community under the [Apache license
|
||||||
|
2.0](./LICENSE).
|
||||||
|
|
||||||
|
It also includes code taken from [`eyre`](https://github.com/yaahc/eyre),
|
||||||
|
and some from [`thiserror`](https://github.com/dtolnay/thiserror), also
|
||||||
|
under the Apache License. Some code is taken from
|
||||||
|
[`ariadne`](https://github.com/zesterer/ariadne), which is MIT licensed.
|
||||||
|
|
||||||
[`miette!`]: https://docs.rs/miette/latest/miette/macro.miette.html
|
[`miette!`]: https://docs.rs/miette/latest/miette/macro.miette.html
|
||||||
[`std::error::Error`]: https://doc.rust-lang.org/nightly/std/error/trait.Error.html
|
[`std::error::Error`]: https://doc.rust-lang.org/nightly/std/error/trait.Error.html
|
||||||
[`Diagnostic`]: https://docs.rs/miette/latest/miette/struct.Diagnostic.html
|
[`Diagnostic`]: https://docs.rs/miette/latest/miette/struct.Diagnostic.html
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@
|
||||||
//!
|
//!
|
||||||
//! #### ... help text
|
//! #### ... help text
|
||||||
//! `miette` provides two facilities for supplying help text for your errors:
|
//! `miette` provides two facilities for supplying help text for your errors:
|
||||||
//
|
//!
|
||||||
//! The first is the `#[help()]` format attribute that applies to structs or
|
//! The first is the `#[help()]` format attribute that applies to structs or
|
||||||
//! enum variants:
|
//! enum variants:
|
||||||
//!
|
//!
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue