pub struct AppError { /* private fields */ }Expand description
Unified application-layer error type.
AppError is the single error type produced by application-layer
handlers. It can wrap a DomainError (with the domain’s kind and
code preserved) or carry an application-specific failure such as
validation, authorization, or a handler routing problem.
§Features
- Implements
ErrorCode, so it can be turned directly into an HTTP / API response without further mapping. - Provides
From<DomainError>so that?lifts domain errors transparently. - Offers application-specific constructors for common failure modes (validation, authorization, handler routing, type coercion).
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::{ErrorCode, ErrorKind};
let err = AppError::validation("email format invalid");
assert_eq!(err.kind(), ErrorKind::InvalidValue);
assert_eq!(err.code(), "VALIDATION_ERROR");
let err = AppError::handler_not_found("CreateUserHandler");
assert_eq!(err.kind(), ErrorKind::Internal);
assert_eq!(err.code(), "HANDLER_NOT_FOUND");Implementations§
Source§impl AppError
impl AppError
Sourcepub fn validation(msg: impl Into<Box<str>>) -> Self
pub fn validation(msg: impl Into<Box<str>>) -> Self
Build a validation error.
Use this for application-layer input validation failures (shape, format, length) that occur before reaching domain logic.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::validation("email format invalid");
assert_eq!(err.code(), "VALIDATION_ERROR");
assert_eq!(err.http_status(), 400);Build an unauthorized error.
Use this when the caller’s identity cannot be verified or the presented credentials are insufficient.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::unauthorized("invalid token");
assert_eq!(err.code(), "UNAUTHORIZED");
assert_eq!(err.http_status(), 401);Sourcepub fn handler_not_found(handler_name: &str) -> Self
pub fn handler_not_found(handler_name: &str) -> Self
Build a “handler not found” error.
Returned by buses (such as crate::InMemoryCommandBus /
crate::InMemoryQueryBus) when no handler is registered for the
dispatched type. The provided handler_name is included in the
error message for diagnostics.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::handler_not_found("CreateUserHandler");
assert_eq!(err.code(), "HANDLER_NOT_FOUND");Sourcepub fn aggregate_not_found(aggregate_type: &str, aggregate_id: &str) -> Self
pub fn aggregate_not_found(aggregate_type: &str, aggregate_id: &str) -> Self
Build an “aggregate not found” error.
Use this in command/query handlers that need to load an aggregate by id and find that the underlying repository returned no record. The aggregate type and id are interpolated into the message.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::aggregate_not_found("User", "user-123");
assert_eq!(err.code(), "AGGREGATE_NOT_FOUND");
assert_eq!(err.http_status(), 404);Sourcepub fn handler_already_registered(handler_name: &str) -> Self
pub fn handler_already_registered(handler_name: &str) -> Self
Build a “handler already registered” error.
Returned by the in-memory buses when the caller attempts to register a second handler for a key that is already populated. Registration is intentionally exclusive to keep the dispatch deterministic.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::handler_already_registered("CreateUserHandler");
assert_eq!(err.code(), "HANDLER_ALREADY_REGISTERED");Sourcepub fn type_mismatch(expected: &str, found: &str) -> Self
pub fn type_mismatch(expected: &str, found: &str) -> Self
Build a “type mismatch” error.
Used by the type-erased buses when a dynamically dispatched value cannot be downcast back to its expected concrete type. This usually indicates a registry corruption or a programming error rather than a runtime user-facing condition.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::type_mismatch("String", "i32");
assert_eq!(err.code(), "TYPE_MISMATCH");Sourcepub fn internal(msg: impl Into<Box<str>>) -> Self
pub fn internal(msg: impl Into<Box<str>>) -> Self
Build a generic internal error.
Use this as a last resort when the failure cannot be expressed by a more specific constructor. Maps to HTTP 500.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorCode;
let err = AppError::internal("unexpected state");
assert_eq!(err.code(), "INTERNAL_ERROR");
assert_eq!(err.http_status(), 500);Sourcepub fn domain_error(&self) -> Option<&DomainError>
pub fn domain_error(&self) -> Option<&DomainError>
Return a reference to the wrapped DomainError, if this AppError
originated from a domain-layer failure via From<DomainError>.
Sourcepub fn get_ref(&self) -> Option<&(dyn StdError + Send + Sync + 'static)>
pub fn get_ref(&self) -> Option<&(dyn StdError + Send + Sync + 'static)>
Return a reference to the inner source error, regardless of whether
it originated as a DomainError or as an arbitrary error wrapped
via AppError::wrap.
Sourcepub fn downcast_ref<E: StdError + 'static>(&self) -> Option<&E>
pub fn downcast_ref<E: StdError + 'static>(&self) -> Option<&E>
Attempt to downcast the inner source to a specific error type.
Supports retrieval of the original concrete error from sources
created with DomainError::custom or AppError::wrap.
Sourcepub fn wrap<E: StdError + Send + Sync + 'static>(
kind: ErrorKind,
code: &'static str,
error: E,
) -> Self
pub fn wrap<E: StdError + Send + Sync + 'static>( kind: ErrorKind, code: &'static str, error: E, ) -> Self
Wrap an arbitrary error into an AppError.
The wrapped error’s type information is preserved and can be
recovered later with AppError::downcast_ref. The error’s
Display value is used as the human-readable message.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorKind;
use std::io;
let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
let err = AppError::wrap(ErrorKind::Internal, "IO_ERROR", io_err);
assert!(err.downcast_ref::<io::Error>().is_some());Sourcepub fn matches(&self, kind: ErrorKind, code: &str) -> bool
pub fn matches(&self, kind: ErrorKind, code: &str) -> bool
Test whether this error matches the given kind/code pair.
Useful in tests and conditional handling code that needs to react to a specific error variant without inspecting the message text.
§Examples
use eventide_application::error::AppError;
use eventide_domain::error::ErrorKind;
let err = AppError::validation("invalid email");
assert!(err.matches(ErrorKind::InvalidValue, "VALIDATION_ERROR"));
assert!(!err.matches(ErrorKind::NotFound, "VALIDATION_ERROR"));Trait Implementations§
Source§impl Error for AppError
impl Error for AppError
Source§fn source(&self) -> Option<&(dyn StdError + 'static)>
fn source(&self) -> Option<&(dyn StdError + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl ErrorCode for AppError
impl ErrorCode for AppError
Source§fn code(&self) -> &str
fn code(&self) -> &str
ErrorKind::default_code).Source§fn http_status(&self) -> u16
fn http_status(&self) -> u16
ErrorKind::http_status).Source§fn is_retryable(&self) -> bool
fn is_retryable(&self) -> bool
ErrorKind::is_retryable).