mirror of https://github.com/zkat/miette.git
Add DiagnosticChain
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
29aead4a94
commit
cfc9c23265
|
|
@ -0,0 +1,93 @@
|
|||
/*!
|
||||
Iterate over error `.diagnostic_source()` chains.
|
||||
*/
|
||||
|
||||
use crate::protocol::Diagnostic;
|
||||
|
||||
/// Iterator of a chain of cause errors.
|
||||
#[derive(Clone, Default)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub(crate) struct DiagnosticChain<'a> {
|
||||
state: Option<ErrorKind<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticChain<'a> {
|
||||
pub(crate) fn from_diagnostic(head: &'a dyn Diagnostic) -> Self {
|
||||
DiagnosticChain {
|
||||
state: Some(ErrorKind::Diagnostic(head)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_stderror(head: &'a (dyn std::error::Error + 'static)) -> Self {
|
||||
DiagnosticChain {
|
||||
state: Some(ErrorKind::StdError(head)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for DiagnosticChain<'a> {
|
||||
type Item = ErrorKind<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(err) = self.state.take() {
|
||||
self.state = err.get_nested();
|
||||
Some(err)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len();
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for DiagnosticChain<'_> {
|
||||
fn len(&self) -> usize {
|
||||
fn depth(d: Option<&ErrorKind<'_>>) -> usize {
|
||||
match d {
|
||||
Some(d) => 1 + depth(d.get_nested().as_ref()),
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
depth(self.state.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum ErrorKind<'a> {
|
||||
Diagnostic(&'a dyn Diagnostic),
|
||||
StdError(&'a (dyn std::error::Error + 'static)),
|
||||
}
|
||||
|
||||
impl<'a> ErrorKind<'a> {
|
||||
fn get_nested(&self) -> Option<ErrorKind<'a>> {
|
||||
match self {
|
||||
ErrorKind::Diagnostic(d) => d
|
||||
.diagnostic_source()
|
||||
.map(ErrorKind::Diagnostic)
|
||||
.or_else(|| d.source().map(ErrorKind::StdError)),
|
||||
ErrorKind::StdError(e) => e.source().map(ErrorKind::StdError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::fmt::Debug for ErrorKind<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ErrorKind::Diagnostic(d) => d.fmt(f),
|
||||
ErrorKind::StdError(e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::fmt::Display for ErrorKind<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ErrorKind::Diagnostic(d) => d.fmt(f),
|
||||
ErrorKind::StdError(e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,9 @@ impl DebugReportHandler {
|
|||
let labels: Vec<_> = labels.collect();
|
||||
diag.field("labels", &format!("{:?}", labels));
|
||||
}
|
||||
if let Some(cause) = diagnostic.diagnostic_source() {
|
||||
diag.field("caused by", &format!("{:?}", cause));
|
||||
}
|
||||
diag.finish()?;
|
||||
writeln!(f)?;
|
||||
writeln!(f, "NOTE: If you're looking for the fancy error reports, install miette with the `fancy` feature, or write your own and hook it up with miette::set_hook().")
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::fmt::{self, Write};
|
|||
|
||||
use owo_colors::{OwoColorize, Style};
|
||||
|
||||
use crate::chain::Chain;
|
||||
use crate::diagnostic_chain::DiagnosticChain;
|
||||
use crate::handlers::theme::*;
|
||||
use crate::protocol::{Diagnostic, Severity};
|
||||
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
||||
|
|
|
|||
|
|
@ -584,6 +584,7 @@ pub use panic::*;
|
|||
pub use protocol::*;
|
||||
|
||||
mod chain;
|
||||
mod diagnostic_chain;
|
||||
mod error;
|
||||
mod eyreish;
|
||||
#[cfg(feature = "fancy-no-backtrace")]
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ pub trait Diagnostic: std::error::Error {
|
|||
}
|
||||
|
||||
/// The cause of the error.
|
||||
fn caused_by(&self) -> Option<&dyn Diagnostic> {
|
||||
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue