132 lines
3.4 KiB
Rust
132 lines
3.4 KiB
Rust
use std::{
|
|
error::Error,
|
|
fmt::{self, Debug},
|
|
};
|
|
use tracing::Level;
|
|
use tracing_error::SpanTrace;
|
|
|
|
#[derive(Debug)]
|
|
pub struct OpaqueError {
|
|
span_trace: SpanTrace,
|
|
pub context: String,
|
|
pub level: Level,
|
|
kind: Option<String>,
|
|
}
|
|
|
|
impl fmt::Display for OpaqueError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
// optional: only print span trace if requested "{:#}"
|
|
if f.alternate() {
|
|
let mut vec = Vec::new();
|
|
|
|
self.span_trace.with_spans(|metadata, _fields| {
|
|
vec.push(metadata.name());
|
|
true
|
|
});
|
|
if vec.len() > 1 {
|
|
write!(f, "trace = {}", vec.pop().unwrap())?;
|
|
}
|
|
vec.reverse();
|
|
for s in vec {
|
|
write!(f, "::{}", s)?;
|
|
}
|
|
};
|
|
write!(f, " {}", self.context)?;
|
|
Ok(())
|
|
}
|
|
}
|
|
impl Error for OpaqueError {}
|
|
impl OpaqueError {
|
|
pub fn create(context: &str) -> OpaqueError {
|
|
Self {
|
|
span_trace: SpanTrace::capture(),
|
|
context: context.to_string(),
|
|
level: Level::ERROR,
|
|
kind: None,
|
|
}
|
|
}
|
|
pub fn create_with_kind(context: &str, kind: &str) -> OpaqueError {
|
|
Self {
|
|
span_trace: SpanTrace::capture(),
|
|
context: context.to_string(),
|
|
level: Level::ERROR,
|
|
kind: Some(kind.to_string()),
|
|
}
|
|
}
|
|
pub fn print_span_trace(&self) -> FancyTrace {
|
|
let mut vec: Vec<(&str, String)> = Vec::new();
|
|
|
|
self.span_trace.with_spans(|metadata, _fields| {
|
|
vec.push((metadata.name(), _fields.into()));
|
|
true
|
|
});
|
|
let str = vec.iter().rfold(String::new(), |mut acc, x| {
|
|
let first = acc.len() == 0;
|
|
if !first {
|
|
// TODO: should this code be hardcoded?
|
|
acc.push_str("\x1b[2m:\x1b[0m");
|
|
}
|
|
|
|
acc.push_str(x.0);
|
|
if !x.1.is_empty() {
|
|
acc.push_str("{");
|
|
acc.push_str(&x.1);
|
|
acc.push_str("}");
|
|
}
|
|
acc
|
|
});
|
|
|
|
FancyTrace { str }
|
|
}
|
|
pub fn set_level(mut self, lvl: Level) -> Self {
|
|
self.level = lvl;
|
|
self
|
|
}
|
|
pub fn get_kind(&self) -> &str {
|
|
match self.kind.as_ref() {
|
|
Some(x) => &x,
|
|
None => &self.context,
|
|
}
|
|
}
|
|
}
|
|
pub struct FancyTrace {
|
|
str: String,
|
|
}
|
|
impl fmt::Display for FancyTrace {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "\x1b[2m{{{{\x1b[0m {} \x1b[2m}}}}\x1b[0m", self.str)
|
|
}
|
|
}
|
|
|
|
impl From<String> for OpaqueError {
|
|
fn from(value: String) -> Self {
|
|
Self {
|
|
span_trace: SpanTrace::capture(),
|
|
context: value,
|
|
level: Level::ERROR,
|
|
kind: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&str> for OpaqueError {
|
|
fn from(value: &str) -> Self {
|
|
Self {
|
|
span_trace: SpanTrace::capture(),
|
|
context: value.to_string(),
|
|
level: Level::ERROR,
|
|
kind: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<crate::packets::ParseErrorTrace> for OpaqueError {
|
|
fn from(value: crate::packets::ParseErrorTrace) -> Self {
|
|
Self {
|
|
span_trace: value.context,
|
|
context: format!("{:?}", value.inner),
|
|
level: Level::ERROR,
|
|
kind: None,
|
|
}
|
|
}
|
|
}
|