mirror of
https://github.com/tokio-rs/axum.git
synced 2024-12-30 16:19:16 +01:00
Document "debugging handler type errors" on Handler
(#1024)
This commit is contained in:
parent
08cbade3cb
commit
0b856b938f
2 changed files with 40 additions and 36 deletions
37
axum/src/docs/debugging_handler_type_errors.md
Normal file
37
axum/src/docs/debugging_handler_type_errors.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
## Debugging handler type errors
|
||||
|
||||
For a function to be used as a handler it must implement the [`Handler`] trait.
|
||||
axum provides blanket implementations for functions that:
|
||||
|
||||
- Are `async fn`s.
|
||||
- Take no more than 16 arguments that all implement [`FromRequest`].
|
||||
- Returns something that implements [`IntoResponse`].
|
||||
- If a closure is used it must implement `Clone + Send` and be
|
||||
`'static`.
|
||||
- Returns a future that is `Send`. The most common way to accidentally make a
|
||||
future `!Send` is to hold a `!Send` type across an await.
|
||||
|
||||
Unfortunately Rust gives poor error messages if you try to use a function
|
||||
that doesn't quite match what's required by [`Handler`].
|
||||
|
||||
You might get an error like this:
|
||||
|
||||
```not_rust
|
||||
error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
|
||||
--> src/main.rs:13:44
|
||||
|
|
||||
13 | let app = Router::new().route("/", get(handler));
|
||||
| ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
|
||||
|
|
||||
::: axum/src/handler/mod.rs:116:8
|
||||
|
|
||||
116 | H: Handler<T, B>,
|
||||
| ------------- required by this bound in `axum::routing::get`
|
||||
```
|
||||
|
||||
This error doesn't tell you _why_ your function doesn't implement
|
||||
[`Handler`]. It's possible to improve the error with the [`debug_handler`]
|
||||
proc-macro from the [axum-macros] crate.
|
||||
|
||||
[axum-macros]: https://docs.rs/axum-macros
|
||||
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
@ -33,42 +33,7 @@
|
|||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Debugging handler type errors
|
||||
//!
|
||||
//! For a function to be used as a handler it must implement the [`Handler`] trait.
|
||||
//! axum provides blanket implementations for functions that:
|
||||
//!
|
||||
//! - Are `async fn`s.
|
||||
//! - Take no more than 16 arguments that all implement [`FromRequest`].
|
||||
//! - Returns something that implements [`IntoResponse`].
|
||||
//! - If a closure is used it must implement `Clone + Send` and be
|
||||
//! `'static`.
|
||||
//! - Returns a future that is `Send`. The most common way to accidentally make a
|
||||
//! future `!Send` is to hold a `!Send` type across an await.
|
||||
//!
|
||||
//! Unfortunately Rust gives poor error messages if you try to use a function
|
||||
//! that doesn't quite match what's required by [`Handler`].
|
||||
//!
|
||||
//! You might get an error like this:
|
||||
//!
|
||||
//! ```not_rust
|
||||
//! error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
|
||||
//! --> src/main.rs:13:44
|
||||
//! |
|
||||
//! 13 | let app = Router::new().route("/", get(handler));
|
||||
//! | ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
|
||||
//! |
|
||||
//! ::: axum/src/handler/mod.rs:116:8
|
||||
//! |
|
||||
//! 116 | H: Handler<T, B>,
|
||||
//! | ------------- required by this bound in `axum::routing::get`
|
||||
//! ```
|
||||
//!
|
||||
//! This error doesn't tell you _why_ your function doesn't implement
|
||||
//! [`Handler`]. It's possible to improve the error with the [`debug_handler`]
|
||||
//! proc-macro from the [axum-macros] crate.
|
||||
//!
|
||||
//! [axum-macros]: https://docs.rs/axum-macros
|
||||
#![doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||
|
||||
use crate::{
|
||||
body::{boxed, Body, Bytes, HttpBody},
|
||||
|
@ -94,6 +59,8 @@ pub use self::into_service::IntoService;
|
|||
/// implemented to closures of the right types.
|
||||
///
|
||||
/// See the [module docs](crate::handler) for more details.
|
||||
///
|
||||
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||
pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
||||
/// The type of future calling this handler returns.
|
||||
type Future: Future<Output = Response> + Send + 'static;
|
||||
|
|
Loading…
Reference in a new issue