Greetings,
Hobby programmer here trying to use axum (I am actually following an actix_web book/project and converting to axum as I read. Axum syntax is closer to what I am used to in python )
I am trying to add error handling now to my program, and there in one place where I cannot understand the fix I've had to add to fix a compiler error. I have to specify axum:Json on a return value and I don't get why.
First. some code
Here is the handler:
pub async fn get_courses_for_tutor(
app_state: extract::Extension<Arc<AppState>>,
extract::Path(tutor_id): extract::Path<i32>,
) -> impl IntoResponse {
let courses = get_courses_for_tutor_db(&app_state.db, tutor_id).await;
courses
}
and the DB access function:
pub async fn get_courses_for_tutor_db(pool: &PgPool, tutor_id: i32) -> Result<Vec<Course>, ZataError> {
let course_rows = sqlx::query_as!(
Course,
"SELECT * FROM ezy_course_c6 where tutor_id = $1",
tutor_id
)
.fetch_all(pool)
.await?;
Ok(course_rows)
}
and my custom error struct implementation
pub enum ZataError {
DBError(String),
ActumError(String),
NotFound(String),
}
impl IntoResponse for ZataError {
type Body = Full<Bytes>;
type BodyError = Infallible;
fn into_response(self) -> Response<Self::Body> {
let (status, error_message) = match self {
ZataError::ActumError(msg) => {
(StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error")
}
ZataError::DBError(msg) => {
(StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error - Database")
}
ZataError::NotFound(msg) => {
(StatusCode::NOT_FOUND, "Not Found")
}
};
let body = Json(json!({
"error": error_message,
}));
(status, body).into_response()
}
}
impl From<AxumError> for ZataError {
fn from(err: AxumError) -> Self {
ZataError::ActumError(err.to_string())
}
}
impl From<SQLxError> for ZataError {
fn from(err: SQLxError) -> Self {
ZataError::DBError(err.to_string())
}
}
trying to run that, I get this error:
the trait bound Vec<Course>: IntoResponse
is not satisfied
the following implementations were found:
<Vec as IntoResponse>
required because of the requirements on the impl of IntoResponse
for Result<Vec<Course>, ZataError>
To solve this, I acn change the return value in pub async fn get_courses_for_tutor from
courses
to
axum::Json(courses)
and then all works fine. But I don't get why. The other solution is probably to implement IntoResponse for the struct Course, but again, I don't get why I would do that on the Course struct.. In my understanding, only the error type I created should require IntoResponse?
Any clue/help to understand is weclome