error_forge/
error.rs

1use std::fmt;
2use std::path::PathBuf;
3use std::io;
4
5#[cfg(feature = "serde")]
6use serde::Serialize;
7
8/// Type alias for error-forge results.
9pub type Result<T> = std::result::Result<T, crate::error::AppError>;
10
11/// Base trait for all custom error variants.
12pub trait ForgeError: std::error::Error + Send + Sync {
13    fn kind(&self) -> &'static str;
14    fn caption(&self) -> &'static str;
15    fn is_retryable(&self) -> bool {
16        false
17    }
18    fn is_fatal(&self) -> bool {
19        true
20    }
21    fn status_code(&self) -> u16 {
22        500
23    }
24    fn exit_code(&self) -> i32 {
25        1
26    }
27}
28
29/// Example enum until macro generates real one.
30#[derive(Debug)]
31#[cfg_attr(feature = "serde", derive(Serialize))]
32pub enum AppError {
33    Config { message: String },
34    Filesystem { path: Option<PathBuf>, source: io::Error },
35    Other { message: String },
36}
37
38impl std::fmt::Display for AppError {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        match self {
41            Self::Config { message } => write!(f, "⚙️ Config: {}", message),
42            Self::Filesystem { path, source } => write!(f, "💾 IO: {:?} ({})", path, source),
43            Self::Other { message } => write!(f, "🚨 Error: {}", message),
44        }
45    }
46}
47
48impl std::error::Error for AppError {
49    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
50        match self {
51            AppError::Filesystem { source, .. } => Some(source),
52            _ => None,
53        }
54    }
55}
56
57impl From<io::Error> for AppError {
58    fn from(e: io::Error) -> Self {
59        AppError::Filesystem { path: None, source: e }
60    }
61}