Here's the relevant code, I can't locate what's wrong. If anyone can help, I'd really appreciate it
pub fn routes() -> Router {
Router::new().route("/api/login", post(api_login))
}
async fn api_login(cookies: Cookies, Json(payload): Json<LoginPayload>) -> Result<Json<Value>> {
info!("Request /login");
// TODO: implement real db/json logic.
if payload.username != "test" && payload.password != "test" {
return Err(Error::LoginFail)
}
……
}
I'm sure this place returns the error——Err(Error::loginFail)
pub enum Error {
LoginFail,
……
}
impl IntoResponse for Error {
fn into_response(self) -> Response {
// create a placeholder Axum response
let mut response = StatusCode::INTERNAL_SERVER_ERROR.into_response();
// Insert the Error into response
response.extensions_mut().insert(self);
dbg!(response.extensions().get::<Error>());
response
}
}
This does generate a response with error when I debug it (You can see this in the screenshot below)
main.rs
:
let app = Router::new()
.merge(web::routes_static::routes())
.merge(web::routes_login::routes())
.layer(middleware::map_response(main_response_mapper))
.layer(middleware::from_fn_with_state(
lc.clone(),
web::mw_auth::mw_ctx_resolver,
))
.layer(CookieManagerLayer::new());
async fn main_response_mapper(mut res: Response) -> Response {
……
// get eventual response error
let service_error = res.extensions().get::<Error>();
……
}
i don't know why service_error
in main_response_mapper
is None
2024-10-29 15:28:05.159 DEBUG c2::error: ->> INTO_RES - AuthFaildNoAuthTokenCookie
[src\error.rs:34:9] response.extensions().get::<crate::error::Error>() = Some(
AuthFaildNoAuthTokenCookie,
)
2024-10-29 15:28:05.159 DEBUG c2: ->> Res_Mapper
[src/main.rs:96:5] response.extensions().get::<crate::error::Error>() = None
It seems that the extensions of response are removed, And I found that I could pass String
values, but my custom Error
would fail
I tried to debug the code, but debugging rust doesn't allow me to see changes to the response variable like other languages. Can you tell me what's wrong with my code or how I can fix it
I ended up not being able to work it out. I took a compromise where strings could be passed through extensions normally, I converted the enum type to a string, and then converted the string to an enum in mapper_response
#[derive(Debug, Deserialize, Clone, AsRefStr, EnumString)]
#[serde(tag = "type", content = "data")]
pub enum Error {
LoginFail,
// Auth error
AuthFaildNoAuthTokenCookie,
AuthFaildTokenFormatWrong,
AuthFaildCtxNotInRequestExt,
// model errors.
ListenerCreationFailed(ListenerCreationError),
ListenerRemoveFailed,
ListenerEditFailed,
}
mapper_response
:
response.extensions_mut().insert(self.as_ref().to_string());