为何执行println后未触发StatusCode::BAD_REQUEST错误?
Rust API认证中间件返回200而非BAD_REQUEST的问题分析
问题场景
调试Rust API时,终端输出如下:
Server running on localhost:3000 auth auth err1 ...
auth err1来自认证中间件的.ok_or()闭包,但接口返回的却是200 OK,并未触发预期的StatusCode::BAD_REQUEST。
对应的中间件代码:
pub async fn auth<T>(mut request: Request<T>, next: Next<T>) -> Result<Response, StatusCode> { println!("auth"); let token = request .headers() .typed_get::<Authorization<Bearer>>() .ok_or({ println!("auth err1"); StatusCode::BAD_REQUEST })? .token() .to_owned(); //other code to connect to DB and retrieve user data... }
原因分析
核心问题是中间件返回的错误没有被Web框架正确转换为HTTP错误响应:
- 当
typed_get返回None时,.ok_or()会执行闭包打印auth err1,并返回Err(StatusCode::BAD_REQUEST),?操作符会将这个错误从函数返回。 - 但多数Rust Web框架(比如Axum)要求中间件的错误类型必须能被转换为合法的HTTP响应。直接返回
StatusCode类型的错误,框架无法正确识别并生成400响应,反而会默认返回200,或忽略错误继续执行后续逻辑。
解决方法
调整错误返回格式,让错误可转换为响应
修改中间件的返回类型,让错误包含状态码和响应体,确保框架能正确生成400响应:pub async fn auth<T>(mut request: Request<T>, next: Next<T>) -> Result<Response, impl IntoResponse> { println!("auth"); let token = request .headers() .typed_get::<Authorization<Bearer>>() .ok_or_else(|| { println!("auth err1"); (StatusCode::BAD_REQUEST, "Missing authorization token") })? .token() .to_owned(); // 后续数据库操作... Ok(next.run(request).await) }这里用
ok_or_else替代ok_or(更符合闭包延迟执行的语义),返回的元组(StatusCode, &str)会自动实现IntoResponsetrait,框架能据此生成正确的400响应。检查框架错误处理规则
确认你使用的Web框架对中间件错误的处理逻辑,确保返回的错误类型实现了IntoResponsetrait。如果直接返回StatusCode,部分框架需要额外转换逻辑才能生成响应。验证中间件挂载正确性
确认auth中间件被正确挂载到需要认证的路由上,没有被路由规则跳过,也没有因中间件顺序问题导致错误处理逻辑未生效。
内容的提问来源于stack exchange,提问作者Russo
相关产品推荐
相关产品推荐

