use crate::access::AccessError;
use crate::dto::error::Error as PublicError;
use std::fmt;
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
#[error("{message}")]
pub struct InternalError {
class: InternalErrorClass,
origin: InternalErrorOrigin,
message: String,
public_error: Option<PublicError>,
}
impl InternalError {
pub fn new(
class: InternalErrorClass,
origin: InternalErrorOrigin,
message: impl Into<String>,
) -> Self {
Self {
class,
origin,
message: message.into(),
public_error: None,
}
}
#[must_use]
pub fn public(err: PublicError) -> Self {
Self {
class: InternalErrorClass::Domain,
origin: InternalErrorOrigin::Domain,
message: err.message.clone(),
public_error: Some(err),
}
}
pub fn domain(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
Self::new(InternalErrorClass::Domain, origin, message)
}
pub fn invariant(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
Self::new(InternalErrorClass::Invariant, origin, message)
}
pub fn infra(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
Self::new(InternalErrorClass::Infra, origin, message)
}
pub fn ops(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
Self::new(InternalErrorClass::Ops, origin, message)
}
pub fn workflow(origin: InternalErrorOrigin, message: impl Into<String>) -> Self {
Self::new(InternalErrorClass::Workflow, origin, message)
}
#[must_use]
pub const fn class(&self) -> InternalErrorClass {
self.class
}
#[must_use]
pub const fn origin(&self) -> InternalErrorOrigin {
self.origin
}
#[must_use]
pub const fn log_fields(&self) -> (InternalErrorClass, InternalErrorOrigin) {
(self.class, self.origin)
}
#[must_use]
pub const fn public_error(&self) -> Option<&PublicError> {
self.public_error.as_ref()
}
}
impl From<AccessError> for InternalError {
fn from(err: AccessError) -> Self {
Self::new(
InternalErrorClass::Access,
InternalErrorOrigin::Access,
err.to_string(),
)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum InternalErrorClass {
Access,
Domain,
Infra,
Ops,
Workflow,
Invariant,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum InternalErrorOrigin {
Access,
Config,
Domain,
Infra,
Ops,
Storage,
Workflow,
}
impl fmt::Display for InternalErrorClass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::Access => "Access",
Self::Domain => "Domain",
Self::Infra => "Infra",
Self::Ops => "Ops",
Self::Workflow => "Workflow",
Self::Invariant => "Invariant",
};
f.write_str(label)
}
}
impl fmt::Display for InternalErrorOrigin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::Access => "Access",
Self::Config => "Config",
Self::Domain => "Domain",
Self::Infra => "Infra",
Self::Ops => "Ops",
Self::Storage => "Storage",
Self::Workflow => "Workflow",
};
f.write_str(label)
}
}