Skip to main content

appletheia_application/command/
command_failure_report.rs

1use std::error::Error;
2use std::fmt::{self, Display};
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
7pub struct CommandFailureReport {
8    pub message: String,
9    pub chain: Vec<String>,
10}
11
12impl CommandFailureReport {
13    pub const DEFAULT_MAX_DEPTH: usize = 16;
14
15    pub fn from_error_with_max_depth(error: &(dyn Error + 'static), max_depth: usize) -> Self {
16        let mut chain = Vec::new();
17
18        let mut current: Option<&(dyn Error + 'static)> = Some(error);
19        let mut depth = 0usize;
20        while let Some(err) = current {
21            if depth >= max_depth {
22                break;
23            }
24            chain.push(err.to_string());
25            current = err.source();
26            depth += 1;
27        }
28
29        let message = chain.first().cloned().unwrap_or_default();
30        Self { message, chain }
31    }
32}
33
34impl<E> From<&E> for CommandFailureReport
35where
36    E: Error + 'static,
37{
38    fn from(value: &E) -> Self {
39        Self::from_error_with_max_depth(value, Self::DEFAULT_MAX_DEPTH)
40    }
41}
42
43impl Display for CommandFailureReport {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}", self.message)
46    }
47}