-
Notifications
You must be signed in to change notification settings - Fork 5
feat: reports (fmt wrappers)
#34
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
Conversation
|
Thanks for your contribution @80Ltrumpet. The newly added |
|
In @Byron's PR of vendoring Codeimpl<E: Error + Send + Sync + 'static> fmt::Debug for Exn<E> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write_frame_recursive(f, self.as_frame(), "", ErrorMode::Display, TreeMode::Linearize)
}
}
impl fmt::Debug for Frame {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write_frame_recursive(f, self, "", ErrorMode::Display, TreeMode::Linearize)
}
}
#[derive(Copy, Clone)]
enum ErrorMode {
Display,
Debug,
}
#[derive(Copy, Clone)]
enum TreeMode {
Linearize,
Verbatim,
}
fn write_frame_recursive(
f: &mut Formatter<'_>,
frame: &Frame,
prefix: &str,
err_mode: ErrorMode,
tree_mode: TreeMode,
) -> fmt::Result {
match err_mode {
ErrorMode::Display => fmt::Display::fmt(frame.as_error(), f),
ErrorMode::Debug => {
write!(f, "{:?}", frame.as_error())
}
}?;
if !f.alternate() {
write_location(f, frame)?;
}
let children = frame.children();
let children_len = children.len();
for (cidx, child) in children.iter().enumerate() {
write!(f, "\n{prefix}|")?;
write!(f, "\n{prefix}└─ ")?;
let child_child_len = child.children().len();
let may_linerarize_chain =
matches!(tree_mode, TreeMode::Linearize) && children_len == 1 && child_child_len == 1;
if may_linerarize_chain {
write_frame_recursive(f, child, prefix, err_mode, tree_mode)?;
} else if cidx < children_len - 1 {
write_frame_recursive(f, child, &format!("{prefix}| "), err_mode, tree_mode)?;
} else {
write_frame_recursive(f, child, &format!("{prefix} "), err_mode, tree_mode)?;
}
}
Ok(())
}
fn write_location(f: &mut Formatter<'_>, exn: &Frame) -> fmt::Result {
let location = exn.location();
write!(f, ", at {}:{}:{}", location.file(), location.line(), location.column())
}
impl<E: Error + Send + Sync + 'static> fmt::Display for Exn<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std::fmt::Display::fmt(&self.frame, f)
}
}
impl fmt::Display for Frame {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
// Avoid printing alternate versions of the debug info, keep it in one line, also print the tree.
write_frame_recursive(f, self, "", ErrorMode::Debug, TreeMode::Verbatim)
} else {
fmt::Display::fmt(self.as_error(), f)
}
}
}
/// A frame in the exception tree.
pub struct Frame {
/// The error that occurred at this frame.
error: Box<dyn Error + Send + Sync + 'static>,
/// The source code location where this exception frame was created.
location: &'static Location<'static>,
/// Child exception frames that provide additional context or source errors.
children: Vec<Frame>,
}In Another flavor is
|
|
To my mind, using the |
Yes, though it looks like better mechanics for doing this are being considered. Sorry to bother y'all. |
This is probably a long-shot, considering related discussions and efforts.
See in particular the doc comments for
report::Compactandreport::Nativefor usage/motivation.