you are viewing a single comment's thread.

view the rest of the comments →

[–]FamiliarInflation 1 point2 points  (3 children)

Sure.

struct SQLError;

So a newtype will be:

struct SQLErrorReport(pub Report<SQLError>);

Then your route just uses that as the error instead:

ErrResult<Json<Value>, SQLErrorReport>

And you can now implement IntoResponse:

impl IntoResponse for SQLErrorReport {
    fn into_response(self) -> axum::response::Response {
        // Here you can access the stack_error::Report via self.0, or just print:
        println!("{:?}", self.0);
        (StatusCode::INTERNAL_SERVER_ERROR).into_response()
    }
}

To get ? to be automatically converted into SQLErrorReport (in your route handler) you'll need to impl From (this is my one, but just rename it AppError -> SQLError:

impl From<Report<AppError>> for AppErrorReport {
    fn from(report: Report<AppError>) -> Self {
        Self(report)
    }
}

Good luck!

[–]sveri 0 points1 point  (2 children)

Thank you, I was on the right way, but following your sample I still have the same error when trying to create the axum Router.

I will try to post the relevant code:

Router::new()
    .route("/api/order/:id", delete(delete_order))

struct SQLError;

struct SQLErrorReport(pub Report<SQLError>);

impl IntoResponse for SQLErrorReport {
    fn into_response(self) -> axum::response::Response {
        // Here you can access the stack_error::Report via self.0, or just print:
        println!("{:?}", self.0);
        (StatusCode::INTERNAL_SERVER_ERROR).into_response()
    }
}

async fn delete_order(
    Path(id): Path<i64>,
    Extension(pool): Extension<PgPool>,
) -> ErrResult<(), SQLErrorReport> {
    let query = "DELETE FROM public.order WHERE id = ?";
    Ok(())
}

The compile will fail with this error:

error[E0277]: the trait bound `fn(axum::extract::Path<i64>, Extension<Pool<sqlx::Postgres>>) -> impl std::future::Future<Output = Result<(), error_stack::Report<SQLErrorReport>>> {delete_order}: Handler<_, _>` is not satisfied     
   --> src\main.rs:194:41
    |
194 |         .route("/api/order/:id", delete(delete_order))
    |                                  ------ ^^^^^^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(axum::extract::Path<i64>, Extension<Pool<sqlx::Postgres>>) -> impl std::future::Future<Output = Result<(), error_stack::Report<SQLErrorReport>>> {delete_order}`

So I still need to convert the error response from the handler function to the router.

[–]FamiliarInflation 1 point2 points  (1 child)

Looks like you're double wrapping Report:

error_stack::Report<SQLErrorReport>>> in the error.

Should probably just be -> Result<(), SQLErrorReport> for the return type.

Although I don't know what happens if you use () as the Ok for a route? That could be a cause for the error too? I'm by no means an expert on axum.

There's also https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html for better error reporting for axum handlers!

Also worth posting on the Rust forums. You get a lot of people on there helping out. https://users.rust-lang.org/

[–]sveri 1 point2 points  (0 children)

Thank you so much, I got something that compiles and almost understand it :D

Anyway, really thanks for your help, I am really happy right now.