zkat / miette

Fancy extension for std::error::Error with pretty, detailed diagnostic printing.
https://docs.rs/miette
Apache License 2.0
1.85k stars 106 forks source link

Help: Sub Errors #364

Closed snowfoxsh closed 2 months ago

snowfoxsh commented 2 months ago

In the readme file an example is shown of multiple sub errors being rendered under the main error message. How can I replicate this behavior?

x failed to find desired version
|> received some ~~~
|> missing field ~~~

Error

zkat commented 2 months ago

That's done through the standard Error::source. You can define this with thiserror by using #[source] on the field that holds the suberror. It's also automatically implemented if you use thiserror's #[from] field.

Additionally, in order to have those sub-errors get the miette treatment themselves, you can use #[source_diagnostic] along with #[source] or #[from] to get things like nested snippets, nested error codes, etc.

A full example:

use miette::Diagnostic;
use thiserror::Error;

#[derive(Debug, Error, Diagnostic)]
struct JsonError {
  #[source]
  #[source_diagnostic]
  inner: SerdeJsonErrorWrapper
}

#[derive(Debug, Error, Diagnostic)]
struct SerdeJsonErrorWrapper(#[from] serde_json::Error);

(I've added an unnecessary indirection just to show #[source_diagnostic], since serde_json::Error is not a miette::Diagnostic).

snowfoxsh commented 2 months ago

Thank you for your patience, that answers my question! Also, Is there a way to set the diagnostic code from with a variable in the sturct? Or can you inherit a code from structure in a field?

zkat commented 2 months ago

Not with the current derive macro. You'd have to implement Diagnostic::code by hand, which is really not a ton of effort, just a bit less concise.