appletheia_application/command/
command_failure_report.rs1use 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}