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

fix(graphical): fix nested error wrapping #358

Merged
merged 8 commits into from
Mar 27, 2024
41 changes: 0 additions & 41 deletions src/eyreish/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,9 @@ use crate::{Diagnostic, LabeledSpan, Report, SourceCode};

use crate as miette;

#[repr(transparent)]
pub(crate) struct DisplayError<M>(pub(crate) M);

#[repr(transparent)]
pub(crate) struct MessageError<M>(pub(crate) M);

pub(crate) struct NoneError;

impl<M> Debug for DisplayError<M>
where
M: Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl<M> Display for DisplayError<M>
where
M: Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl<M> StdError for DisplayError<M> where M: Display + 'static {}
impl<M> Diagnostic for DisplayError<M> where M: Display + 'static {}

impl<M> Debug for MessageError<M>
where
M: Display + Debug,
Expand All @@ -56,21 +30,6 @@ where
impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
impl<M> Diagnostic for MessageError<M> where M: Display + Debug + 'static {}

impl Debug for NoneError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Debug::fmt("Option was None", f)
}
}

impl Display for NoneError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("Option was None", f)
}
}

impl StdError for NoneError {}
impl Diagnostic for NoneError {}

#[repr(transparent)]
pub(crate) struct BoxedError(pub(crate) Box<dyn Diagnostic + Send + Sync>);

Expand Down
15 changes: 9 additions & 6 deletions src/handlers/graphical.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt::{self, Write};

use owo_colors::{OwoColorize, Style, StyledList};
use unicode_width::UnicodeWidthChar;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

use crate::diagnostic_chain::{DiagnosticChain, ErrorKind};
use crate::handlers::theme::*;
Expand Down Expand Up @@ -225,7 +225,7 @@ impl GraphicalReportHandler {
self.render_related(f, diagnostic, src)?;
if let Some(footer) = &self.footer {
writeln!(f)?;
let width = self.termwidth.saturating_sub(4);
let width = self.termwidth.saturating_sub(2);
let mut opts = textwrap::Options::new(width)
.initial_indent(" ")
.subsequent_indent(" ")
Expand Down Expand Up @@ -265,16 +265,15 @@ impl GraphicalReportHandler {
);
write!(header, "{}", link)?;
writeln!(f, "{}", header)?;
writeln!(f)?;
} else if let Some(code) = diagnostic.code() {
write!(header, "{}", code.style(severity_style),)?;
if self.links == LinkStyle::Text && diagnostic.url().is_some() {
let url = diagnostic.url().unwrap(); // safe
write!(header, " ({})", url.style(self.theme.styles.link))?;
}
writeln!(f, "{}", header)?;
writeln!(f)?;
}
writeln!(f)?;
Ok(())
}

Expand Down Expand Up @@ -354,8 +353,12 @@ impl GraphicalReportHandler {
inner_renderer.footer = None;
// Cause chains are already flattened, so don't double-print the nested error
inner_renderer.with_cause_chain = false;
// Since everything from here on is indented, shrink the virtual terminal
inner_renderer.termwidth -= rest_indent.width();
inner_renderer.render_report(&mut inner, diag)?;

// If there was no header, remove the leading newline
let inner = inner.trim_start_matches('\n');
writeln!(f, "{}", self.wrap(&inner, opts))?;
}
ErrorKind::StdError(err) => {
Expand All @@ -370,7 +373,7 @@ impl GraphicalReportHandler {

fn render_footer(&self, f: &mut impl fmt::Write, diagnostic: &(dyn Diagnostic)) -> fmt::Result {
if let Some(help) = diagnostic.help() {
let width = self.termwidth.saturating_sub(4);
let width = self.termwidth.saturating_sub(2);
let initial_indent = " help: ".style(self.theme.styles.help).to_string();
let mut opts = textwrap::Options::new(width)
.initial_indent(&initial_indent)
Expand Down Expand Up @@ -398,8 +401,8 @@ impl GraphicalReportHandler {
let mut inner_renderer = self.clone();
// Re-enable the printing of nested cause chains for related errors
inner_renderer.with_cause_chain = true;
writeln!(f)?;
for rel in related {
writeln!(f)?;
match rel.severity() {
Some(Severity::Error) | None => write!(f, "Error: ")?,
Some(Severity::Warning) => write!(f, "Warning: ")?,
Expand Down
6 changes: 6 additions & 0 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ fn related() {
#[derive(Error, Debug, Diagnostic)]
#[error("welp")]
#[diagnostic(code(foo::bar::baz))]
#[allow(dead_code)]
struct Foo {
#[related]
related: Vec<Baz>,
}

#[derive(Error, Debug, Diagnostic)]
#[allow(dead_code)]
enum Bar {
#[error("variant1")]
#[diagnostic(code(foo::bar::baz))]
Expand All @@ -29,6 +31,7 @@ fn related() {

#[derive(Error, Debug, Diagnostic)]
#[error("welp2")]
#[allow(dead_code)]
struct Baz;
}

Expand All @@ -37,6 +40,7 @@ fn related_report() {
#[derive(Error, Debug, Diagnostic)]
#[error("welp")]
#[diagnostic(code(foo::bar::baz))]
#[allow(dead_code)]
struct Foo {
#[related]
related: Vec<Report>,
Expand Down Expand Up @@ -288,6 +292,7 @@ fn test_snippet_named_struct() {
#[derive(Debug, Diagnostic, Error)]
#[error("welp")]
#[diagnostic(code(foo::bar::baz))]
#[allow(dead_code)]
struct Foo<'a> {
#[source_code]
src: &'a str,
Expand All @@ -310,6 +315,7 @@ fn test_snippet_unnamed_struct() {
#[derive(Debug, Diagnostic, Error)]
#[error("welp")]
#[diagnostic(code(foo::bar::baz))]
#[allow(dead_code)]
struct Foo<'a>(
#[source_code] &'a str,
#[label("{0}")] SourceSpan,
Expand Down