tokio-rs / axum

Ergonomic and modular web framework built with Tokio, Tower, and Hyper
19.18k stars 1.06k forks source link

Handler<_, _>` is not satisfied the following other types implement trait `Handler<T, S>`: #2851

Closed JonnyJiang123 closed 3 months ago

JonnyJiang123 commented 3 months ago

How can I resolve it? It just like official sample, but I got an error:

图片

Bug Report

图片

Version

├── axum v0.7.5 │ ├── axum-core v0.4.3

Platform

stable-aarch64-apple-darwin unchanged - rustc 1.80.0 (051478957 2024-07-21) macos version 14.5 (23F79) macbook m1 pro

Crates

[package]
name = "thumbor"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7.5" # web 服务器
anyhow = "1" # 错误处理
base64 = "0.22.1" # base64 编码/解码
bytes = "1" # 处理字节流
image = "0.25.2" # 处理图片
lazy_static = "1" # 通过宏更方便地初始化静态变量
lru = "0.12.3" # LRU 缓存
percent-encoding = "2" # url 编码/解码
photon-rs = "0.3" # 图片效果
prost = "0.13.1" # protobuf 处理
reqwest = "0.12.5" # HTTP cliebnt
serde = { version = "1", features = ["derive"] } # 序列化/反序列化数据
tokio = { version = "1", features = ["full"] } # 异步处理
tower = { version = "0.4", features = [
    "util",
    "timeout",
    "load-shed",
    "limit",
] } # 服务处理及中间件
tower-http = { version = "0.5.2", features = [
    "add-extension",
    "compression-full",
    "trace",
] } # http 中间件
tracing = "0.1" # 日志和追踪
tracing-subscriber = "0.3.18" # 日志和追踪

[build-dependencies]
prost-build = "0.13.1" # 编译 protobuf

Description

Handler<, >is not satisfied the following other types implement traitHandler<T, S>`:

I tried this code:

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt().init();
    let cahce: Cache = Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1024).unwrap())));
    let app = Router::new()
        .route("/image/:spec/:url", get(generate))
        .with_state(cahce)
        .layer(AddExtensionLayer::new(cahce));
    let addr = "127.0.0.1:3000";
    tracing::info!("listening on {}", addr);
    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn generate(
    State(cache): State<Cache>,
    Path(Param { spec, url }): Path<Param>,
) -> Result<(HeaderMap, Vec<u8>), StatusCode> {
    let url = percent_decode_str(&url).decode_utf8_lossy();
    let spec: ImageSpec = spec
        .as_str()
        .try_into()
        .map_err(|_| StatusCode::BAD_REQUEST)?;
    let data = retrieve_image(&url, cache)
        .await
        .map_err(|_| StatusCode::BAD_REQUEST)?;

    // 使用 image engine 处理
    let mut engine: Photon = data
        .try_into()
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    engine.apply(&spec.specs);
    let image = engine.generate(ImageFormat::Jpeg);
    info!("Finished processing: image size {}", image.len());

    let mut header = HeaderMap::new();
    header.insert("content-type", HeaderValue::from_static("image/jpeg"));
    Ok((header, image))
}

and error is

图片
JonnyJiang123 commented 3 months ago
图片

Here is Param struct definition

mladedav commented 3 months ago

Try adding axum::debug_handler as an attribute to your handler. It should give you a better error. I suspect your return type doesn't implement IntoResponse because you should use http::StatusCode instead of the reqwest one. But really, do try the attribute if it gives you other suggestions.

Also next time please use GitHub discussions for questions like this rather than opening an issue.

JonnyJiang123 commented 3 months ago

v

图片 I changed, but it was error just like before. 图片

JonnyJiang123 commented 3 months ago

I try to add debug_handler macro, but it also error. 图片 error is 图片

JonnyJiang123 commented 3 months ago

I solved it! Ok, it is not easy! When use std::sync::Mutext in asyn block like tokio, it is seem has some problems,but it can replaced with tokio::sync::Mutex. The whole code are as follow: 图片

jplatte commented 3 months ago

That's nice that you figured it out. For some further info on the different kinds of mutexes, see tokio's documentation.

Also in the future, please avoid posting screenshots of code, and use code blocks like you did for the Cargo.toml in the issue description.

JonnyJiang123 commented 3 months ago

thank you!