pub struct AutumnError { /* private fields */ }Expand description
Framework error type wrapping any error with an HTTP status code.
§Usage
The ? operator converts any std::error::Error into an AutumnError
with status 500 Internal Server Error:
use autumn_web::prelude::*;
#[get("/")]
async fn handler() -> AutumnResult<&'static str> {
autumn_web::reexports::tokio::fs::read_to_string("missing.txt").await?; // becomes 500 on error
Ok("ok")
}For expected errors, use a status refinement constructor:
use autumn_web::prelude::*;
#[get("/users/{id}")]
async fn get_user(axum::extract::Path(id): axum::extract::Path<i32>) -> AutumnResult<String> {
if id < 0 {
return Err(AutumnError::bad_request(
std::io::Error::other("id must be positive"),
));
}
Ok(format!("user {id}"))
}§Why no Error impl
AutumnError intentionally does not implement std::error::Error.
Doing so would conflict with the blanket From<E: Error> impl (the
reflexive From<T> for T would overlap). This type is a response
wrapper, not a propagatable error.
Implementations§
Source§impl AutumnError
impl AutumnError
Sourcepub const fn with_status(self, status: StatusCode) -> Self
pub const fn with_status(self, status: StatusCode) -> Self
Override the HTTP status code.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err: AutumnError = std::io::Error::other("forbidden").into();
let err = err.with_status(StatusCode::FORBIDDEN);
assert_eq!(err.status(), StatusCode::FORBIDDEN);Sourcepub fn internal_server_error(err: impl Error + Send + Sync + 'static) -> Self
pub fn internal_server_error(err: impl Error + Send + Sync + 'static) -> Self
Create a 500 Internal Server Error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::internal_server_error(std::io::Error::other("boom"));
assert_eq!(err.status(), StatusCode::INTERNAL_SERVER_ERROR);Sourcepub fn not_found(err: impl Error + Send + Sync + 'static) -> Self
pub fn not_found(err: impl Error + Send + Sync + 'static) -> Self
Create a 404 Not Found error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::not_found(std::io::Error::other("no such user"));
assert_eq!(err.status(), StatusCode::NOT_FOUND);Sourcepub fn bad_request(err: impl Error + Send + Sync + 'static) -> Self
pub fn bad_request(err: impl Error + Send + Sync + 'static) -> Self
Create a 400 Bad Request error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::bad_request(std::io::Error::other("invalid input"));
assert_eq!(err.status(), StatusCode::BAD_REQUEST);Sourcepub fn unprocessable(err: impl Error + Send + Sync + 'static) -> Self
pub fn unprocessable(err: impl Error + Send + Sync + 'static) -> Self
Create a 422 Unprocessable Entity error.
Use this for validation failures where the request is syntactically valid but semantically incorrect.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::unprocessable(std::io::Error::other("age must be positive"));
assert_eq!(err.status(), StatusCode::UNPROCESSABLE_ENTITY);Create a 503 Service Unavailable error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::service_unavailable(std::io::Error::other("pool exhausted"));
assert_eq!(err.status(), StatusCode::SERVICE_UNAVAILABLE);Create a 401 Unauthorized error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::unauthorized(std::io::Error::other("not logged in"));
assert_eq!(err.status(), StatusCode::UNAUTHORIZED);Sourcepub fn forbidden(err: impl Error + Send + Sync + 'static) -> Self
pub fn forbidden(err: impl Error + Send + Sync + 'static) -> Self
Create a 403 Forbidden error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::forbidden(std::io::Error::other("not allowed"));
assert_eq!(err.status(), StatusCode::FORBIDDEN);Sourcepub fn validation(details: HashMap<String, Vec<String>>) -> Self
pub fn validation(details: HashMap<String, Vec<String>>) -> Self
Create a 422 Unprocessable Entity error with field-level
validation details.
Use this when a request fails multiple field-specific validation rules
(e.g., in a form submission). It attaches the details parameter, a mapping
of field names to their respective error messages, so the client can display
errors next to the relevant inputs.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
use std::collections::HashMap;
let mut errors = HashMap::new();
errors.insert("username".to_string(), vec!["Username is taken".to_string()]);
let err = AutumnError::validation(errors);
assert_eq!(err.status(), StatusCode::UNPROCESSABLE_ENTITY);Sourcepub fn internal_server_error_msg(msg: impl Into<String>) -> Self
pub fn internal_server_error_msg(msg: impl Into<String>) -> Self
Create a 500 Internal Server Error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::internal_server_error_msg("Database explosion");
assert_eq!(err.status(), StatusCode::INTERNAL_SERVER_ERROR);Sourcepub fn not_found_msg(msg: impl Into<String>) -> Self
pub fn not_found_msg(msg: impl Into<String>) -> Self
Create a 404 Not Found error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::not_found_msg("No such user");
assert_eq!(err.status(), StatusCode::NOT_FOUND);
assert_eq!(err.to_string(), "No such user");Sourcepub fn bad_request_msg(msg: impl Into<String>) -> Self
pub fn bad_request_msg(msg: impl Into<String>) -> Self
Create a 400 Bad Request error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::bad_request_msg("Invalid input parameter");
assert_eq!(err.status(), StatusCode::BAD_REQUEST);Sourcepub fn unprocessable_msg(msg: impl Into<String>) -> Self
pub fn unprocessable_msg(msg: impl Into<String>) -> Self
Create a 422 Unprocessable Entity error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::unprocessable_msg("Title is required");
assert_eq!(err.status(), StatusCode::UNPROCESSABLE_ENTITY);Create a 401 Unauthorized error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::unauthorized_msg("Please log in to continue");
assert_eq!(err.status(), StatusCode::UNAUTHORIZED);Sourcepub fn forbidden_msg(msg: impl Into<String>) -> Self
pub fn forbidden_msg(msg: impl Into<String>) -> Self
Create a 403 Forbidden error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::forbidden_msg("You lack admin privileges");
assert_eq!(err.status(), StatusCode::FORBIDDEN);Create a 503 Service Unavailable error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::service_unavailable_msg("Database connection pool exhausted");
assert_eq!(err.status(), StatusCode::SERVICE_UNAVAILABLE);Sourcepub fn conflict(err: impl Error + Send + Sync + 'static) -> Self
pub fn conflict(err: impl Error + Send + Sync + 'static) -> Self
Create a 409 Conflict error.
Use this for optimistic-lock conflicts surfaced by repository update
calls when the client’s expected version is stale.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::conflict(std::io::Error::other("stale version"));
assert_eq!(err.status(), StatusCode::CONFLICT);Sourcepub fn conflict_msg(msg: impl Into<String>) -> Self
pub fn conflict_msg(msg: impl Into<String>) -> Self
Create a 409 Conflict error from a plain string message.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err = AutumnError::conflict_msg("Concurrent edit: please reload and retry");
assert_eq!(err.status(), StatusCode::CONFLICT);Sourcepub const fn status(&self) -> StatusCode
pub const fn status(&self) -> StatusCode
Returns the HTTP status code associated with this error.
§Examples
use autumn_web::error::AutumnError;
use http::StatusCode;
let err: AutumnError = std::io::Error::other("boom").into();
assert_eq!(err.status(), StatusCode::INTERNAL_SERVER_ERROR);Sourcepub fn source_chain(&self) -> Vec<String>
pub fn source_chain(&self) -> Vec<String>
Return the wrapped error’s source chain as displayable messages.
The top-level AutumnError display already prints the wrapped error
message, so this list starts at that wrapped error’s first source.
Trait Implementations§
Source§impl Debug for AutumnError
impl Debug for AutumnError
Source§impl Display for AutumnError
impl Display for AutumnError
Source§impl<E> From<E> for AutumnError
impl<E> From<E> for AutumnError
Source§impl IntoResponse for AutumnError
impl IntoResponse for AutumnError
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
Auto Trait Implementations§
impl Freeze for AutumnError
impl !RefUnwindSafe for AutumnError
impl Send for AutumnError
impl Sync for AutumnError
impl Unpin for AutumnError
impl UnsafeUnpin for AutumnError
impl !UnwindSafe for AutumnError
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
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> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> HxResponseExt for Twhere
T: IntoResponse,
impl<T> HxResponseExt for Twhere
T: IntoResponse,
Source§fn hx_location(self, url: &str) -> Response
fn hx_location(self, url: &str) -> Response
HX-Location).Source§fn hx_push_url(self, url: &str) -> Response
fn hx_push_url(self, url: &str) -> Response
HX-Push-Url).Source§fn hx_redirect(self, url: &str) -> Response
fn hx_redirect(self, url: &str) -> Response
HX-Redirect).Source§fn hx_refresh(self) -> Response
fn hx_refresh(self) -> Response
HX-Refresh).Source§fn hx_replace_url(self, url: &str) -> Response
fn hx_replace_url(self, url: &str) -> Response
HX-Replace-Url).Source§fn hx_reswap(self, swap: &str) -> Response
fn hx_reswap(self, swap: &str) -> Response
HX-Reswap).Source§fn hx_retarget(self, target: &str) -> Response
fn hx_retarget(self, target: &str) -> Response
HX-Retarget).Source§fn hx_trigger(self, event: &str) -> Response
fn hx_trigger(self, event: &str) -> Response
HX-Trigger).Source§fn hx_trigger_after_settle(self, event: &str) -> Response
fn hx_trigger_after_settle(self, event: &str) -> Response
HX-Trigger-After-Settle).Source§fn hx_trigger_after_swap(self, event: &str) -> Response
fn hx_trigger_after_swap(self, event: &str) -> Response
HX-Trigger-After-Swap).Source§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> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T, Conn> RunQueryDsl<Conn> for T
impl<T, Conn> RunQueryDsl<Conn> for T
Source§fn execute<'conn, 'query>(
self,
conn: &'conn mut Conn,
) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
Source§fn load<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Source§fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
Stream] with the returned rows. Read moreSource§fn get_result<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
Source§fn get_results<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Vec with the affected rows. Read moreSource§impl<T> Scoped for T
impl<T> Scoped for T
Source§fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
ScopeQuery for this type. Resolves the
registered scope at .load() time, not here.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.