如何在同一个 Axum 处理程序中返回成功和错误情况?

Fin*_*ber 3 rust rust-axum

好的,我有一个 axum 处理程序,看起来有点像这样:

#[debug_handler]
async fn handler(
    State(server_state): State<Arc<Server>>,
    Query(query_params): Query<Query>,
) -> impl IntoResponse {
    match server_state.store.handle(query_params).await {
        Ok(res) => (StatusCode::OK, Json(res)),
        Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, Json(err))
    }
}
Run Code Online (Sandbox Code Playgroud)

此操作失败并出现以下错误:

   |
42 | /     match server_state.store.handle(query_params).await {
43 | |         Ok(res) => (StatusCode::OK, Json(res)),
   | |                   -------------------------- this is found to be of type `(StatusCode, axum::Json<Vec<Data>>)`
44 | |         Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, Json(err))
   | |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Vec`, found enum `sqlx::Error`
45 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note: expected tuple `(StatusCode, axum::Json<Vec<Data>>)`
              found tuple `(StatusCode, axum::Json<sqlx::Error>)`

Run Code Online (Sandbox Code Playgroud)

我明白为什么会发生错误。匹配表达式的两个分支没有相同的返回类型。

但问题是如何解决这个问题?我不确定是否必须以某种方式转换sqlx::Error为正常情况是否有意义。

我能想到的另一种方法是有一个响应结构......类似于

struct Response {
   body: Option<Data>,
   error: Option<sqlx::Error>
}
Run Code Online (Sandbox Code Playgroud)

None如果成功的话将会出现错误。主体将None在发生错误时出现。

问题是,我不确定这是否是 Axum 处理此问题的普遍可接受的方式?

maz*_*azi 7

答案有点晚了,但我认为在这种情况下最简单的方法是将 into_response() 应用于两个 match-arm 结果:

 match server_state.store.handle(query_params).await {
    Ok(res) => (StatusCode::OK, Json(res)).into_response(),
    Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, Json(err)).into_response()
}
Run Code Online (Sandbox Code Playgroud)

最好的问候托马斯