1use crate::access::AccessError;
2use crate::dto::error::Error as PublicError;
3use std::fmt;
4use thiserror::Error as ThisError;
5
6#[derive(Debug, ThisError)]
21#[error("{message}")]
22pub struct InternalError {
23 class: InternalErrorClass,
24 origin: InternalErrorOrigin,
25 message: String,
26 public_error: Option<PublicError>,
27}
28
29impl InternalError {
30 pub fn new(
31 class: InternalErrorClass,
32 origin: InternalErrorOrigin,
33 message: impl Into<String>,
34 ) -> Self {
35 Self {
36 class,
37 origin,
38 message: message.into(),
39 public_error: None,
40 }
41 }
42
43 #[must_use]
44 pub fn public(err: PublicError) -> Self {
45 Self {
46 class: InternalErrorClass::Domain,
47 origin: InternalErrorOrigin::Domain,
48 message: err.message.clone(),
49 public_error: Some(err),
50 }
51 }
52
53 pub fn domain(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
54 Self::new(InternalErrorClass::Domain, origin, message)
55 }
56
57 pub fn invariant(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
58 Self::new(InternalErrorClass::Invariant, origin, message)
59 }
60
61 pub fn infra(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
62 Self::new(InternalErrorClass::Infra, origin, message)
63 }
64
65 pub fn ops(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
66 Self::new(InternalErrorClass::Ops, origin, message)
67 }
68
69 pub fn workflow(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
70 Self::new(InternalErrorClass::Workflow, origin, message)
71 }
72
73 #[must_use]
74 pub const fn class(&self) -> InternalErrorClass {
75 self.class
76 }
77
78 #[must_use]
79 pub const fn origin(&self) -> InternalErrorOrigin {
80 self.origin
81 }
82
83 #[must_use]
84 pub const fn log_fields(&self) -> (InternalErrorClass, InternalErrorOrigin) {
85 (self.class, self.origin)
86 }
87
88 #[must_use]
89 pub const fn public_error(&self) -> Option<&PublicError> {
90 self.public_error.as_ref()
91 }
92}
93
94impl From<AccessError> for InternalError {
95 fn from(err: AccessError) -> Self {
96 Self::new(
97 InternalErrorClass::Access,
98 InternalErrorOrigin::Access,
99 err.to_string(),
100 )
101 }
102}
103
104#[derive(Clone, Copy, Debug, Eq, PartialEq)]
109pub enum InternalErrorClass {
110 Access,
111 Domain,
112 Infra,
113 Ops,
114 Workflow,
115 Invariant,
116}
117
118#[derive(Clone, Copy, Debug, Eq, PartialEq)]
123pub enum InternalErrorOrigin {
124 Access,
125 Config,
126 Domain,
127 Infra,
128 Ops,
129 Storage,
130 Workflow,
131}
132
133impl fmt::Display for InternalErrorClass {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 let label = match self {
136 Self::Access => "Access",
137 Self::Domain => "Domain",
138 Self::Infra => "Infra",
139 Self::Ops => "Ops",
140 Self::Workflow => "Workflow",
141 Self::Invariant => "Invariant",
142 };
143
144 f.write_str(label)
145 }
146}
147
148impl fmt::Display for InternalErrorOrigin {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 let label = match self {
151 Self::Access => "Access",
152 Self::Config => "Config",
153 Self::Domain => "Domain",
154 Self::Infra => "Infra",
155 Self::Ops => "Ops",
156 Self::Storage => "Storage",
157 Self::Workflow => "Workflow",
158 };
159
160 f.write_str(label)
161 }
162}