pub struct Error { /* private fields */ }Expand description
The primary error type for the modo framework.
Error carries:
- an HTTP
StatusCodethat will be used as the response status, - a human-readable
messagestring, - an optional structured
detailspayload (arbitrary JSON), - an optional boxed
sourceerror for causal chaining, - an optional static
error_codestring that survives the response pipeline, - an optional static
locale_keythat lets the default error handler translate the message at response-build time, - a
laggedflag used by the SSE broadcaster to signal that a subscriber dropped messages.
§Conversion to HTTP response
Calling into_response() produces a JSON body:
{ "error": { "status": 404, "message": "user not found" } }If with_details was called, a "details" field is included.
A copy of the error (without source) is also stored in response extensions so middleware
can inspect it after the fact.
§Clone behaviour
Cloning an Error drops the source field because Box<dyn Error> is not Clone.
The error_code, locale_key, details, and all other fields are preserved.
Implementations§
Source§impl Error
impl Error
Sourcepub fn new(status: StatusCode, message: impl Into<String>) -> Self
pub fn new(status: StatusCode, message: impl Into<String>) -> Self
Create a new error with the given HTTP status code and message.
Sourcepub fn with_source(
status: StatusCode,
message: impl Into<String>,
source: impl Error + Send + Sync + 'static,
) -> Self
pub fn with_source( status: StatusCode, message: impl Into<String>, source: impl Error + Send + Sync + 'static, ) -> Self
Create a new error with a status code, message, and a boxed source error.
Use chain instead when constructing errors with the builder pattern.
Sourcepub fn localized(status: StatusCode, key: &'static str) -> Self
pub fn localized(status: StatusCode, key: &'static str) -> Self
Create an error whose message is a translation key.
The key is stored in the locale_key slot and is also used as the raw
message. When the
default_error_handler runs
and a Translator is present in the request
extensions (installed by
I18nLayer), it resolves key into the
user-facing string at response-build time. Without that middleware (or
without a Translator), the response falls back to the raw key — making
the behaviour predictable and easy to spot in logs.
This constructor leaves error_code, details, and source unset;
chain with_code,
with_details, or chain
afterwards if needed.
§Kwargs and logging
Translation kwargs ({count}, {name}, etc.) are not yet supported at
the Error level — the default handler calls tr.t(key, &[]) with no
arguments. When you need interpolation, attach a descriptive fallback
message via Error::with_locale_key and run translation (with kwargs)
inside a custom handler passed to
error_handler.
Also note that Debug and [Display] print the raw key (because the
fallback message is the key), which makes structured logs look like
errors.user.not_found rather than human text. Prefer
Error::with_locale_key when you want log-friendly output alongside
the translation tag.
Sourcepub fn status(&self) -> StatusCode
pub fn status(&self) -> StatusCode
Returns the HTTP status code of this error.
Sourcepub fn with_details(self, details: Value) -> Self
pub fn with_details(self, details: Value) -> Self
Attach a structured JSON details payload (builder-style).
Sourcepub fn chain(self, source: impl Error + Send + Sync + 'static) -> Self
pub fn chain(self, source: impl Error + Send + Sync + 'static) -> Self
Attach a source error (builder-style).
Sourcepub fn with_code(self, code: &'static str) -> Self
pub fn with_code(self, code: &'static str) -> Self
Attach a static error code to preserve error identity through the response pipeline.
The error code is included in the copy stored in response extensions and can be retrieved
after into_response() via Error::error_code.
This is a builder method: the existing message, status, locale_key,
details, and source fields are preserved — only error_code is
replaced.
Sourcepub fn error_code(&self) -> Option<&'static str>
pub fn error_code(&self) -> Option<&'static str>
Returns the error code, if one was set.
Sourcepub fn with_locale_key(self, key: &'static str) -> Self
pub fn with_locale_key(self, key: &'static str) -> Self
Tag an existing error with a translation key (builder-style).
Unlike Error::localized, this preserves the current message — use
it when you already have a descriptive fallback string and want to add a
translation key alongside it. The
default_error_handler will
prefer the translated value whenever a
Translator is available in the request
extensions, and otherwise keep the stored message untouched.
This is a builder method: the existing message, status, error_code,
details, and source fields are preserved — only locale_key is
replaced.
Sourcepub fn locale_key(&self) -> Option<&'static str>
pub fn locale_key(&self) -> Option<&'static str>
Returns the translation key, if one was set via Error::localized or
Error::with_locale_key.
Sourcepub fn source_as<T: Error + 'static>(&self) -> Option<&T>
pub fn source_as<T: Error + 'static>(&self) -> Option<&T>
Downcast the source error to a concrete type.
Returns None if no source is set or if the source is not of type T.
Sourcepub fn bad_request(msg: impl Into<String>) -> Self
pub fn bad_request(msg: impl Into<String>) -> Self
Create a 400 Bad Request error.
Create a 401 Unauthorized error.
Sourcepub fn payload_too_large(msg: impl Into<String>) -> Self
pub fn payload_too_large(msg: impl Into<String>) -> Self
Create a 413 Payload Too Large error.
Sourcepub fn unprocessable_entity(msg: impl Into<String>) -> Self
pub fn unprocessable_entity(msg: impl Into<String>) -> Self
Create a 422 Unprocessable Entity error.
Sourcepub fn too_many_requests(msg: impl Into<String>) -> Self
pub fn too_many_requests(msg: impl Into<String>) -> Self
Create a 429 Too Many Requests error.
Sourcepub fn bad_gateway(msg: impl Into<String>) -> Self
pub fn bad_gateway(msg: impl Into<String>) -> Self
Create a 502 Bad Gateway error.
Sourcepub fn gateway_timeout(msg: impl Into<String>) -> Self
pub fn gateway_timeout(msg: impl Into<String>) -> Self
Create a 504 Gateway Timeout error.
Trait Implementations§
Source§impl Clone for Error
Clones the error, dropping the source field (which is not Clone).
impl Clone for Error
Clones the error, dropping the source field (which is not Clone).
All other fields — status, message, error_code, locale_key, details, and
lagged — are preserved.
Source§impl Error for Error
impl Error for Error
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<Error> for Error
Converts libsql::Error into modo::Error with
appropriate HTTP status codes:
impl From<Error> for Error
Converts libsql::Error into modo::Error with
appropriate HTTP status codes:
- Unique/primary-key constraint violations become
409 Conflict. - Foreign-key violations become
400 Bad Request. QueryReturnedNoRowsbecomes404 Not Found.- Everything else becomes
500 Internal Server Error.
Source§impl From<ValidationError> for Error
impl From<ValidationError> for Error
Source§fn from(ve: ValidationError) -> Self
fn from(ve: ValidationError) -> Self
Source§impl IntoResponse for Error
Converts Error into an axum Response.
impl IntoResponse for Error
Converts Error into an axum Response.
Produces a JSON body of the form:
{ "error": { "status": 422, "message": "validation failed" } }If with_details was called, a "details" key is added under "error".
A copy of the error (without the source field) is stored in response extensions under
the type Error so that downstream middleware can inspect it.
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
Auto Trait Implementations§
impl Freeze for Error
impl !RefUnwindSafe for Error
impl Send for Error
impl Sync for Error
impl Unpin for Error
impl UnsafeUnpin for Error
impl !UnwindSafe for Error
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, S> Handler<IntoResponseHandler, S> for T
impl<T, S> Handler<IntoResponseHandler, S> for T
Source§fn call(
self,
_req: Request<Body>,
_state: S,
) -> <T as Handler<IntoResponseHandler, S>>::Future
fn call( self, _req: Request<Body>, _state: S, ) -> <T as Handler<IntoResponseHandler, S>>::Future
Source§fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>where
L: Layer<HandlerService<Self, T, S>> + Clone,
<L as Layer<HandlerService<Self, T, S>>>::Service: Service<Request<Body>>,
fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>where
L: Layer<HandlerService<Self, T, S>> + Clone,
<L as Layer<HandlerService<Self, T, S>>>::Service: Service<Request<Body>>,
tower::Layer to the handler. Read moreSource§fn with_state(self, state: S) -> HandlerService<Self, T, S>
fn with_state(self, state: S) -> HandlerService<Self, T, S>
Service by providing the stateSource§impl<H, T> HandlerWithoutStateExt<T> for H
impl<H, T> HandlerWithoutStateExt<T> for H
Source§fn into_service(self) -> HandlerService<H, T, ()>
fn into_service(self) -> HandlerService<H, T, ()>
Service and no state.Source§fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, ()>>
fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, ()>>
MakeService and no state. Read moreSource§fn into_make_service_with_connect_info<C>(
self,
) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C>
fn into_make_service_with_connect_info<C>( self, ) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C>
MakeService which stores information
about the incoming connection and has no state. Read moreSource§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.