gpt4 book ai didi

rust - 如何正确处理 Warp 路由的错误

转载 作者:行者123 更新时间:2023-12-05 04:47:53 27 4
gpt4 key购买 nike

我正在尝试构建一个不平凡的 warp将 REST 应用程序集成到模块中,同时优雅地处理错误和拒绝。它没有按我预期的方式工作。考虑这个简单的应用程序:

主要.rs

use warp_sample::routes;

#[tokio::main]
async fn main() {
warp::serve(routes::convert_route()).run(([127, 0, 0, 1], 8080)).await;
}

路线.rs

use warp::{Filter, Rejection, Reply};
use crate::handlers;

pub fn convert_route() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path("convert")
.and(warp::path::param::<String>())
.map(|v: String| {
handlers::convert_str(&v).or_else(|e| e)
})
}

处理程序.rs

use warp::{Reply, Rejection};

pub fn convert_str(s: &str) -> Result<impl Reply, Rejection>{
match s.parse::<i32>() {
Ok(s) => Ok(warp::reply()),
Err(_) => Err(warp::reject())
}
}

这不会编译,因为在 routes.rs 中我试图在闭包中返回一个 Rejection 结构,它与 impl Reply 的返回类型不匹配。

我如何让它工作?我试图更改 convert_route 的返回类型,但这不适用于 warp::serve

对于加分,你能告诉我如何在成功时在处理程序中包含纯文本响应,并在出现错误时包含不同的状态代码吗?

这对奖金不起作用,但它告诉你我在想什么。

pub fn convert_str(s: &str) -> Result<impl Reply, Rejection>{
match s.parse::<i32>() {
Ok(s) => Ok(warp::body(s)),
Err(_) => Err(warp::Rejection {
reason: Reason::BadRequest,
})
}
}

最佳答案

你应该只使用 map 当你正在做的操作是绝对正确的。如果您希望能够返回拒绝,您应该使用 and_then 反而。在您的示例中,convert_route更改为以下代码时可正确编译。

pub fn convert_route() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path("convert")
.and(warp::path::param::<String>())
.and_then(|v: String| async move { convert_str(&v) })
}

当然在这个例子中,convert_str有点微不足道并且convert_route可以在没有它的情况下通过简单地更改 .and(warp::path::param::<String>()) 中的类型来重写,但我认为该函数更多地包含在您的实际代码中。

对于奖金,您需要创建自己的拒绝类型,这将允许您使用 recover 来处理它。 .完整代码:

use warp::{hyper::StatusCode, reject::Reject, Filter, Rejection, Reply};

pub fn convert_route() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path("convert")
.and(warp::path::param::<String>())
.and_then(|v: String| async move { convert_str(&v) })
.recover(|err: Rejection| async move {
if let Some(ConversionError) = err.find() {
Ok(StatusCode::BAD_REQUEST)
} else {
Err(err)
}
})
}

#[derive(Debug)]
struct ConversionError;
impl Reject for ConversionError {}

pub fn convert_str(s: &str) -> Result<impl Reply, Rejection> {
match s.parse::<i32>() {
Ok(s) => Ok(s.to_string()),
Err(_) => Err(warp::reject::custom(ConversionError)),
}
}

#[tokio::main]
async fn main() {
warp::serve(convert_route())
.run(([127, 0, 0, 1], 8080))
.await;
}

关于rust - 如何正确处理 Warp 路由的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68331445/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com