Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b4855e7
Apply basic design to the core (and http) library
the10thWiz Nov 18, 2024
f130928
Add FromError and update Fairings
the10thWiz Nov 18, 2024
270ff68
Update sync_db_pools for new API
the10thWiz Nov 18, 2024
ef3f077
Update db_pools
the10thWiz Nov 18, 2024
e44c5c9
Update websockets
the10thWiz Nov 18, 2024
16654b6
Update rocket_dyn_templates
the10thWiz Nov 18, 2024
8a19e70
Add todo notes
the10thWiz Nov 18, 2024
9aaad74
Fixing more compile issues
the10thWiz Nov 18, 2024
b1b0444
Complete initial implementation
the10thWiz Nov 20, 2024
848768b
Update with working implementation
the10thWiz Nov 20, 2024
44dddab
Add tests, and update collition logic
the10thWiz Nov 20, 2024
49c4334
Add better tests
the10thWiz Nov 20, 2024
9ab0650
Update derive docs
the10thWiz Nov 22, 2024
9ec71ad
Updating docs
the10thWiz Nov 22, 2024
fd07363
Clean up initial implementation
the10thWiz Nov 22, 2024
80ce0d7
Fix minor issues
the10thWiz Nov 22, 2024
5edfe06
Remove old dependency
the10thWiz Nov 22, 2024
b544068
Re-add display for error to tracing
the10thWiz Nov 22, 2024
068aa34
Fix more small things
the10thWiz Nov 22, 2024
eb707ce
Update guide for typed catchers
the10thWiz Feb 2, 2025
fbc61ae
Fix unit tests and imports
the10thWiz Aug 28, 2025
a252457
Add link to GitHub in the quickstart page (#2949)
Nikitf777 Aug 27, 2025
0bd6d37
Remove unknown rust_analyzer cfg (#2937)
the10thWiz Aug 27, 2025
a9a3e07
Cleanup code
the10thWiz Sep 2, 2025
78776ee
Keep error type's name to provide more useful messages
the10thWiz Sep 2, 2025
fa2fd5d
Fix help message to only appear on appropriate errors
the10thWiz Sep 2, 2025
5938cac
Revert partial fix since the actual fix is in master
the10thWiz Sep 2, 2025
14d4127
Import Left & Right in more examples
the10thWiz Sep 2, 2025
a2d3aa4
Rename `StateMissing` to `StateError`
the10thWiz Sep 2, 2025
5614329
Fix tests to use updated types
the10thWiz Sep 6, 2025
42c32ae
Simplify argument logic by combining duplicate code between route and…
the10thWiz Sep 6, 2025
fb96d59
Silence warning
the10thWiz Sep 6, 2025
bc93673
Remove `AsStatus` type since we can just directly implement `From` fo…
the10thWiz Sep 14, 2025
79077a2
Separate `Forward` and `Error` types on `FromRequest`
the10thWiz Sep 14, 2025
4ccc5b8
Complete updates for tests and doc tests
the10thWiz Sep 15, 2025
1200310
Support #[error(status = ...)] on enums as well
the10thWiz Sep 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions contrib/db_pools/codegen/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ pub fn derive_database(input: TokenStream) -> TokenStream {

#[rocket::async_trait]
impl<'r> rocket::request::FromRequest<'r> for &'r #decorated_type {
type Error = ();
type Error = rocket::http::Status;

async fn from_request(
req: &'r rocket::request::Request<'_>
) -> rocket::request::Outcome<Self, Self::Error> {
match #db_ty::fetch(req.rocket()) {
Some(db) => rocket::outcome::Outcome::Success(db),
None => rocket::outcome::Outcome::Error((
rocket::http::Status::InternalServerError, ()))
None => rocket::outcome::Outcome::Error(
rocket::http::Status::InternalServerError)
}
}
}
Expand Down
29 changes: 25 additions & 4 deletions contrib/db_pools/lib/src/database.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

use rocket::catcher::{Static, TypedError};
use rocket::{error, Build, Ignite, Phase, Rocket, Sentinel, Orbit};
use rocket::fairing::{self, Fairing, Info, Kind};
use rocket::request::{FromRequest, Outcome, Request};
Expand Down Expand Up @@ -278,17 +279,37 @@ impl<D: Database> Fairing for Initializer<D> {
}
}

/// Possible errors when aquiring a database connection
#[derive(Debug, PartialEq, Eq)]
pub enum DbError<E> {
ServiceUnavailable(E),
InternalError,
}

impl<E: 'static> Static for DbError<E> {}

impl<'r, E: Send + Sync + 'static> TypedError<'r> for DbError<E> {
fn status(&self) -> Status {
match self {
Self::ServiceUnavailable(_) => Status::ServiceUnavailable,
Self::InternalError => Status::InternalServerError,
}
}
}

#[rocket::async_trait]
impl<'r, D: Database> FromRequest<'r> for Connection<D> {
type Error = Option<<D::Pool as Pool>::Error>;
impl<'r, D: Database> FromRequest<'r> for Connection<D>
where <D::Pool as Pool>::Error: Send + Sync + 'static
{
type Error = DbError<<D::Pool as Pool>::Error>;

async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match D::fetch(req.rocket()) {
Some(db) => match db.get().await {
Ok(conn) => Outcome::Success(Connection(conn)),
Err(e) => Outcome::Error((Status::ServiceUnavailable, Some(e))),
Err(e) => Outcome::Error(DbError::ServiceUnavailable(e)),
},
None => Outcome::Error((Status::InternalServerError, None)),
None => Outcome::Error(DbError::InternalError),
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions contrib/dyn_templates/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::fmt;
use std::borrow::Cow;

use rocket::{Request, Rocket, Ignite, Sentinel};
use rocket::http::{Status, ContentType};
use rocket::outcome::Outcome;
use rocket::{Ignite, Request, Rocket, Sentinel, StateMissing};
use rocket::http::ContentType;
use rocket::request::{self, FromRequest};
use rocket::serde::Serialize;

Expand Down Expand Up @@ -152,18 +153,19 @@ impl Sentinel for Metadata<'_> {
/// (`500`) is returned.
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Metadata<'r> {
type Error = ();
type Error = StateMissing;

async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
request.rocket().state::<ContextManager>()
.map(|cm| request::Outcome::Success(Metadata(cm)))
.unwrap_or_else(|| {
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
match request.rocket().state::<ContextManager>() {
Some(cm) => Outcome::Success(Metadata(cm)),
None => {
error!(
"uninitialized template context: missing `Template::fairing()`.\n\
To use templates, you must attach `Template::fairing()`."
);

request::Outcome::Error((Status::InternalServerError, ()))
})
request::Outcome::Error(StateMissing("Template::fairing()"))
}
}
}
}
2 changes: 1 addition & 1 deletion contrib/dyn_templates/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl Template {
/// extension and a fixed-size body containing the rendered template. If
/// rendering fails, an `Err` of `Status::InternalServerError` is returned.
impl<'r> Responder<'r, 'static> for Template {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'r, 'static> {
let ctxt = req.rocket()
.state::<ContextManager>()
.ok_or_else(|| {
Expand Down
4 changes: 2 additions & 2 deletions contrib/sync_db_pools/codegen/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea

#[#rocket::async_trait]
impl<'r> #rocket::request::FromRequest<'r> for #guard_type {
type Error = ();
type Error = ::rocket_sync_db_pools::ConnectionMissing;

async fn from_request(
__r: &'r #rocket::request::Request<'_>
) -> #rocket::request::Outcome<Self, ()> {
) -> #rocket::request::Outcome<Self, Self::Error> {
<#conn>::from_request(__r).await.map(Self)
}
}
Expand Down
22 changes: 17 additions & 5 deletions contrib/sync_db_pools/lib/src/connection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::any::type_name;
use std::sync::Arc;
use std::marker::PhantomData;

use rocket::catcher::{Static, TypedError};
use rocket::{Phase, Rocket, Ignite, Sentinel};
use rocket::fairing::{AdHoc, Fairing};
use rocket::request::{Request, Outcome, FromRequest};
Expand Down Expand Up @@ -221,19 +223,29 @@ impl<K, C: Poolable> Drop for ConnectionPool<K, C> {
}
}

/// Error for a managed state element not being present.
#[derive(Debug, PartialEq, Eq)]
pub struct ConnectionMissing(pub &'static str);

impl Static for ConnectionMissing {}

impl<'r> TypedError<'r> for ConnectionMissing {
fn status(&self) -> Status { Status::InternalServerError }
}

#[rocket::async_trait]
impl<'r, K: 'static, C: Poolable> FromRequest<'r> for Connection<K, C> {
type Error = ();
type Error = ConnectionMissing;

#[inline]
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, ()> {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match request.rocket().state::<ConnectionPool<K, C>>() {
Some(c) => c.get().await.or_error((Status::ServiceUnavailable, ())),
Some(c) => c.get().await.or_error(ConnectionMissing(type_name::<K>())),
None => {
let conn = std::any::type_name::<K>();
let conn = type_name::<K>();
error!("`{conn}::fairing()` is not attached\n\
the fairing must be attached to use `{conn} in routes.");
Outcome::Error((Status::InternalServerError, ()))
Outcome::Error(ConnectionMissing(type_name::<K>()))
}
}
}
Expand Down
Loading
Loading