Skip to content

Commit 6427db2

Browse files
committed
Updates to improve many aspects
1 parent a59cb04 commit 6427db2

File tree

25 files changed

+324
-180
lines changed

25 files changed

+324
-180
lines changed

contrib/dyn_templates/src/template.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -265,19 +265,21 @@ impl Template {
265265
/// extension and a fixed-size body containing the rendered template. If
266266
/// rendering fails, an `Err` of `Status::InternalServerError` is returned.
267267
impl<'r> Responder<'r, 'static> for Template {
268-
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
269-
let ctxt = req.rocket()
270-
.state::<ContextManager>()
271-
.ok_or_else(|| {
272-
error!(
273-
"uninitialized template context: missing `Template::fairing()`.\n\
274-
To use templates, you must attach `Template::fairing()`."
275-
);
276-
277-
Status::InternalServerError
278-
})?;
268+
type Error = std::convert::Infallible;
269+
fn respond_to(self, req: &'r Request<'_>) -> response::Outcome<'static, Self::Error> {
270+
if let Some(ctxt) = req.rocket().state::<ContextManager>() {
271+
match self.finalize(&ctxt.context()) {
272+
Ok(v) => v.respond_to(req),
273+
Err(s) => response::Outcome::Forward(s),
274+
}
275+
} else {
276+
error!(
277+
"uninitialized template context: missing `Template::fairing()`.\n\
278+
To use templates, you must attach `Template::fairing()`."
279+
);
279280

280-
self.finalize(&ctxt.context())?.respond_to(req)
281+
response::Outcome::Forward(Status::InternalServerError)
282+
}
281283
}
282284
}
283285

contrib/ws/src/websocket.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ impl<'r> FromRequest<'r> for WebSocket {
238238
}
239239

240240
impl<'r, 'o: 'r> Responder<'r, 'o> for Channel<'o> {
241-
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
241+
type Error = std::convert::Infallible;
242+
fn respond_to(self, _: &'r Request<'_>) -> response::Outcome<'o, Self::Error> {
242243
Response::build()
243244
.raw_header("Sec-Websocket-Version", "13")
244245
.raw_header("Sec-WebSocket-Accept", self.ws.key.clone())
@@ -250,7 +251,8 @@ impl<'r, 'o: 'r> Responder<'r, 'o> for Channel<'o> {
250251
impl<'r, 'o: 'r, S> Responder<'r, 'o> for MessageStream<'o, S>
251252
where S: futures::Stream<Item = Result<Message>> + Send + 'o
252253
{
253-
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
254+
type Error = std::convert::Infallible;
255+
fn respond_to(self, _: &'r Request<'_>) -> response::Outcome<'o, Self::Error> {
254256
Response::build()
255257
.raw_header("Sec-Websocket-Version", "13")
256258
.raw_header("Sec-WebSocket-Accept", self.ws.key.clone())

core/codegen/src/attribute/catch/mod.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ fn error_type(guard: &ErrorGuard) -> TokenStream {
2121
fn error_guard_decl(guard: &ErrorGuard) -> TokenStream {
2222
let (ident, ty) = (guard.ident.rocketized(), &guard.ty);
2323
quote_spanned! { ty.span() =>
24-
let #ident: &#ty = match #_catcher::downcast(__error_init.as_ref()) {
24+
let #ident: &#ty = match #_catcher::downcast(__error_init) {
2525
Some(v) => v,
26-
None => return #_Result::Err((#__status, __error_init)),
26+
None => return #_Result::Err(#__status),
2727
};
2828
}
2929
}
@@ -43,7 +43,7 @@ fn request_guard_decl(guard: &Guard) -> TokenStream {
4343
"request guard forwarding; trying next catcher"
4444
);
4545

46-
return #_Err((#__status, __error_init));
46+
return #_Err(#__status);
4747
},
4848
#[allow(unreachable_code)]
4949
#Outcome::Error((__c, __e)) => {
@@ -56,7 +56,7 @@ fn request_guard_decl(guard: &Guard) -> TokenStream {
5656
"request guard failed; forwarding to 500 handler"
5757
);
5858

59-
return #_Err((#Status::InternalServerError, __error_init));
59+
return #_Err(#Status::InternalServerError);
6060
}
6161
};
6262
}
@@ -97,7 +97,11 @@ pub fn _catch(
9797

9898
let catcher_response = quote_spanned!(return_type_span => {
9999
let ___responder = #user_catcher_fn_name(#(#parameter_names),*) #dot_await;
100-
#_response::Responder::respond_to(___responder, #__req).map_err(|s| (s, __error_init))?
100+
match #_response::Responder::respond_to(___responder, #__req) {
101+
#Outcome::Success(v) => v,
102+
// If the responder fails, we drop any typed error, and convert to 500
103+
#Outcome::Error(_) | #Outcome::Forward(_) => return Err(#Status::InternalServerError),
104+
}
101105
});
102106

103107
// Generate the catcher, keeping the user's input around.
@@ -116,7 +120,7 @@ pub fn _catch(
116120
fn monomorphized_function<'__r>(
117121
#__status: #Status,
118122
#__req: &'__r #Request<'_>,
119-
__error_init: #ErasedError<'__r>,
123+
__error_init: #_Option<&'__r (dyn #TypedError<'__r> + '__r)>,
120124
) -> #_catcher::BoxFuture<'__r> {
121125
#_Box::pin(async move {
122126
#error_guard

core/codegen/src/attribute/route/mod.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,17 @@ fn query_decls(route: &Route) -> Option<TokenStream> {
113113
"{_err}"
114114
); } }
115115
);
116+
let __e = #resolve_error!(__e);
116117
::rocket::trace::info!(
117118
target: concat!("rocket::codegen::route::", module_path!()),
118-
error_type = ::std::any::type_name_of_val(&__e),
119+
error_type = __e.name(),
119120
"Forwarding error"
120121
);
121122

122123
return #Outcome::Forward((
123124
#__data,
124125
#Status::UnprocessableEntity,
125-
#resolve_error!(__e)
126+
__e.val
126127
));
127128
}
128129

@@ -134,7 +135,7 @@ fn query_decls(route: &Route) -> Option<TokenStream> {
134135
fn request_guard_decl(guard: &Guard) -> TokenStream {
135136
let (ident, ty) = (guard.fn_ident.rocketized(), &guard.ty);
136137
define_spanned_export!(ty.span() =>
137-
__req, __data, _request, display_hack, FromRequest, Outcome, resolve_error
138+
__req, __data, _request, display_hack, FromRequest, Outcome, resolve_error, _None
138139
);
139140

140141
quote_spanned! { ty.span() =>
@@ -150,21 +151,22 @@ fn request_guard_decl(guard: &Guard) -> TokenStream {
150151
"request guard forwarding"
151152
);
152153

153-
return #Outcome::Forward((#__data, __e, #resolve_error!()));
154+
return #Outcome::Forward((#__data, __e, #_None));
154155
},
155156
#[allow(unreachable_code)]
156157
#Outcome::Error((__c, __e)) => {
158+
let __err = #resolve_error!(__e);
157159
::rocket::trace::info!(
158160
name: "failure",
159161
target: concat!("rocket::codegen::route::", module_path!()),
160162
parameter = stringify!(#ident),
161163
type_name = stringify!(#ty),
162-
reason = %#display_hack!(&__e),
163-
error_type = ::std::any::type_name_of_val(&__e),
164+
// reason = %#display_hack!(&__e),
165+
error_type = __err.name,
164166
"request guard failed"
165167
);
166168

167-
return #Outcome::Error((__c, #resolve_error!(__e)));
169+
return #Outcome::Error((__c, __err.val));
168170
}
169171
};
170172
}
@@ -179,17 +181,18 @@ fn param_guard_decl(guard: &Guard) -> TokenStream {
179181

180182
// Returned when a dynamic parameter fails to parse.
181183
let parse_error = quote!({
184+
let __err = #resolve_error!(__error);
182185
::rocket::trace::info!(
183186
name: "forward",
184187
target: concat!("rocket::codegen::route::", module_path!()),
185188
parameter = #name,
186189
type_name = stringify!(#ty),
187-
reason = %#display_hack!(&__error),
188-
error_type = ::std::any::type_name_of_val(&__error),
190+
// reason = %#display_hack!(&__error),
191+
error_type = __err.name,
189192
"path guard forwarding"
190193
);
191194

192-
#Outcome::Forward((#__data, #Status::UnprocessableEntity, #resolve_error!(__error)))
195+
#Outcome::Forward((#__data, #Status::UnprocessableEntity, __err.val))
193196
});
194197

195198
// All dynamic parameters should be found if this function is being called;
@@ -214,7 +217,7 @@ fn param_guard_decl(guard: &Guard) -> TokenStream {
214217
return #Outcome::Forward((
215218
#__data,
216219
#Status::InternalServerError,
217-
#resolve_error!()
220+
#_None
218221
));
219222
}
220223
}
@@ -235,7 +238,7 @@ fn param_guard_decl(guard: &Guard) -> TokenStream {
235238
fn data_guard_decl(guard: &Guard) -> TokenStream {
236239
let (ident, ty) = (guard.fn_ident.rocketized(), &guard.ty);
237240
define_spanned_export!(ty.span() =>
238-
__req, __data, display_hack, FromData, Outcome, resolve_error);
241+
__req, __data, display_hack, FromData, Outcome, resolve_error, _None);
239242

240243
quote_spanned! { ty.span() =>
241244
let #ident: #ty = match <#ty as #FromData>::from_data(#__req, #__data).await {
@@ -250,21 +253,22 @@ fn data_guard_decl(guard: &Guard) -> TokenStream {
250253
"data guard forwarding"
251254
);
252255

253-
return #Outcome::Forward((__d, __e, #resolve_error!()));
256+
return #Outcome::Forward((__d, __e, #_None));
254257
}
255258
#[allow(unreachable_code)]
256259
#Outcome::Error((__c, __e)) => {
260+
let __e = #resolve_error!(__e);
257261
::rocket::trace::info!(
258262
name: "failure",
259263
target: concat!("rocket::codegen::route::", module_path!()),
260264
parameter = stringify!(#ident),
261265
type_name = stringify!(#ty),
262-
reason = %#display_hack!(&__e),
263-
error_type = ::std::any::type_name_of_val(&__e),
266+
// reason = %#display_hack!(&__e),
267+
error_type = __e.name,
264268
"data guard failed"
265269
);
266270

267-
return #Outcome::Error((__c, #resolve_error!(__e)));
271+
return #Outcome::Error((__c, __e.val));
268272
}
269273
};
270274
}

core/codegen/src/exports.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ define_exported_paths! {
8686
_Vec => ::std::vec::Vec,
8787
_Cow => ::std::borrow::Cow,
8888
_ExitCode => ::std::process::ExitCode,
89+
_trace => ::rocket::trace,
8990
display_hack => ::rocket::error::display_hack,
9091
BorrowMut => ::std::borrow::BorrowMut,
9192
Outcome => ::rocket::outcome::Outcome,
@@ -103,7 +104,7 @@ define_exported_paths! {
103104
Catcher => ::rocket::Catcher,
104105
Status => ::rocket::http::Status,
105106
resolve_error => ::rocket::catcher::resolve_typed_catcher,
106-
ErasedError => ::rocket::catcher::ErasedError,
107+
TypedError => ::rocket::catcher::TypedError,
107108
}
108109

109110
macro_rules! define_spanned_export {

core/http/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ memchr = "2"
3636
stable-pattern = "0.1"
3737
cookie = { version = "0.18", features = ["percent-encode"] }
3838
state = "0.6"
39-
transient = { version = "0.4" }
39+
transient = { version = "0.4", path = "/home/matthew/transient" }
4040

4141
[dependencies.serde]
4242
version = "1.0"

core/lib/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ default = ["http2", "tokio-macros", "trace"]
2727
http2 = ["hyper/http2", "hyper-util/http2"]
2828
http3-preview = ["s2n-quic", "s2n-quic-h3", "tls"]
2929
secrets = ["cookie/private", "cookie/key-expansion"]
30-
json = ["serde_json"]
31-
msgpack = ["rmp-serde"]
30+
json = ["serde_json", "transient/serde_json"]
31+
msgpack = ["rmp-serde", "transient/rmp-serde"]
3232
uuid = ["uuid_", "rocket_http/uuid", "transient/uuid"]
3333
tls = ["rustls", "tokio-rustls", "rustls-pemfile"]
3434
mtls = ["tls", "x509-parser"]
@@ -74,7 +74,7 @@ tokio-stream = { version = "0.1.6", features = ["signal", "time"] }
7474
cookie = { version = "0.18", features = ["percent-encode"] }
7575
futures = { version = "0.3.30", default-features = false, features = ["std"] }
7676
state = "0.6"
77-
transient = { version = "0.4" }
77+
transient = { version = "0.4", features = ["either"], path = "/home/matthew/transient" }
7878

7979
# tracing
8080
tracing = { version = "0.1.40", default-features = false, features = ["std", "attributes"] }

core/lib/src/catcher/catcher.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ use crate::http::ext::IntoOwned;
88
use crate::response::Response;
99
use crate::request::Request;
1010
use crate::http::{Status, ContentType, uri};
11-
use crate::catcher::{Handler, BoxFuture};
12-
13-
use super::ErasedError;
11+
use crate::catcher::{BoxFuture, TypedError, Handler};
1412

1513
/// An error catching route.
1614
///
@@ -324,7 +322,7 @@ impl Catcher {
324322

325323
impl Default for Catcher {
326324
fn default() -> Self {
327-
fn handler<'r>(s: Status, req: &'r Request<'_>, _e: ErasedError<'r>) -> BoxFuture<'r> {
325+
fn handler<'r>(s: Status, req: &'r Request<'_>, _e: Option<&(dyn TypedError<'r> + 'r)>) -> BoxFuture<'r> {
328326
Box::pin(async move { Ok(default_handler(s, req)) })
329327
}
330328

@@ -344,7 +342,7 @@ pub struct StaticInfo {
344342
/// The catcher's error type.
345343
pub error_type: Option<(TypeId, &'static str)>,
346344
/// The catcher's handler, i.e, the annotated function.
347-
pub handler: for<'r> fn(Status, &'r Request<'_>, ErasedError<'r>) -> BoxFuture<'r>,
345+
pub handler: for<'r> fn(Status, &'r Request<'_>, Option<&'r (dyn TypedError<'r> + 'r)>) -> BoxFuture<'r>,
348346
/// The file, line, and column where the catcher was defined.
349347
pub location: (&'static str, u32, u32),
350348
}

core/lib/src/catcher/handler.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::{Request, Response};
2+
use crate::catcher::TypedError;
23
use crate::http::Status;
34

4-
use super::ErasedError;
5-
65
/// Type alias for the return type of a [`Catcher`](crate::Catcher)'s
76
/// [`Handler::handle()`].
8-
pub type Result<'r> = std::result::Result<Response<'r>, (crate::http::Status, ErasedError<'r>)>;
7+
pub type Result<'r> = std::result::Result<Response<'r>, crate::http::Status>;
98

109
/// Type alias for the return type of a _raw_ [`Catcher`](crate::Catcher)'s
1110
/// [`Handler`].
@@ -101,19 +100,19 @@ pub trait Handler: Cloneable + Send + Sync + 'static {
101100
/// Nevertheless, failure is allowed, both for convenience and necessity. If
102101
/// an error handler fails, Rocket's default `500` catcher is invoked. If it
103102
/// succeeds, the returned `Response` is used to respond to the client.
104-
async fn handle<'r>(&self, status: Status, req: &'r Request<'_>, error: ErasedError<'r>)
103+
async fn handle<'r>(&self, status: Status, req: &'r Request<'_>, error: Option<&'r (dyn TypedError<'r> + 'r)>)
105104
-> Result<'r>;
106105
}
107106

108107
// We write this manually to avoid double-boxing.
109108
impl<F: Clone + Sync + Send + 'static> Handler for F
110-
where for<'x> F: Fn(Status, &'x Request<'_>, ErasedError<'x>) -> BoxFuture<'x>,
109+
where for<'x> F: Fn(Status, &'x Request<'_>, Option<&'x (dyn TypedError<'x> + 'x)>) -> BoxFuture<'x>,
111110
{
112-
fn handle<'r, 'life0, 'life1, 'async_trait>(
111+
fn handle<'r, 'life0, 'life1, 'life2, 'async_trait>(
113112
&'life0 self,
114113
status: Status,
115114
req: &'r Request<'life1>,
116-
error: ErasedError<'r>,
115+
error: Option<&'r (dyn TypedError<'r> + 'r)>,
117116
) -> BoxFuture<'r>
118117
where 'r: 'async_trait,
119118
'life0: 'async_trait,
@@ -126,7 +125,7 @@ impl<F: Clone + Sync + Send + 'static> Handler for F
126125

127126
// Used in tests! Do not use, please.
128127
#[doc(hidden)]
129-
pub fn dummy_handler<'r>(_: Status, _: &'r Request<'_>, _: ErasedError<'r>) -> BoxFuture<'r> {
128+
pub fn dummy_handler<'r>(_: Status, _: &'r Request<'_>, _: Option<&(dyn TypedError<'r> + 'r)>) -> BoxFuture<'r> {
130129
Box::pin(async move { Ok(Response::new()) })
131130
}
132131

0 commit comments

Comments
 (0)