mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-02 17:31:53 +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
|
#![doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||||
//!
|
|
||||||
//! 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
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
body::{boxed, Body, Bytes, HttpBody},
|
body::{boxed, Body, Bytes, HttpBody},
|
||||||
|
@ -94,6 +59,8 @@ pub use self::into_service::IntoService;
|
||||||
/// implemented to closures of the right types.
|
/// implemented to closures of the right types.
|
||||||
///
|
///
|
||||||
/// See the [module docs](crate::handler) for more details.
|
/// 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 {
|
pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
|
||||||
/// The type of future calling this handler returns.
|
/// The type of future calling this handler returns.
|
||||||
type Future: Future<Output = Response> + Send + 'static;
|
type Future: Future<Output = Response> + Send + 'static;
|
||||||
|
|
Loading…
Reference in a new issue