Skip to main content

AppError

Struct AppError 

Source
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

Source

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);
Source

pub fn unauthorized(msg: impl Into<Box<str>>) -> Self

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);
Source

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");
Source

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);
Source

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");
Source

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");
Source

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);
Source

pub fn kind(&self) -> ErrorKind

Return the ErrorKind category of this error.

Source

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>.

Source

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.

Source

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.

Source

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());
Source

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 Debug for AppError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for AppError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for AppError

Source§

fn source(&self) -> Option<&(dyn StdError + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl ErrorCode for AppError

Source§

fn kind(&self) -> ErrorKind

Return the error’s category.
Source§

fn code(&self) -> &str

Return the error code (defaults to ErrorKind::default_code).
Source§

fn http_status(&self) -> u16

Return the HTTP status code (defaults to ErrorKind::http_status).
Source§

fn is_retryable(&self) -> bool

Whether the error is retryable (defaults to ErrorKind::is_retryable).
Source§

impl From<DomainError> for AppError

Source§

fn from(e: DomainError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.