tokio-rs/axum

Can we take inspiration from how Pavex handles errors?

Opened this issue · 3 comments

  • I have looked for existing issues (including closed) about this

Feature Request

Motivation

There is a great recent blogpost from Luca Palmieri which outlines some DX issues with how Axum and Actix are handling errors. I understand that having a link instead of the description isn't great in an issue, but doubt I could summarize the idea better than the blogpost does. Though it's quite short anyways.

And in the end of the article he describe a little bit different approach on how he designed error handling for Pavex. To me it seems like a similar API could be implemented for Axum and work great.

Proposal

The overall idea in short is to skip implementing IntoResponse for Result and instead provide .error_handler method to register error handlers, where in the userspace various logic could be handled.

enum MyError {
  Foo,
  Bar
}

router.error_handler(my_error_handler);

async fn my_error_handler(err: MyError) -> impl IntoResponse {
  // log it
  // trace it
  // convert it to response
}

Does it seem doable for Axum and do you think it make sense? If you are open to the idea than do you think implementing this in Axum would be doable for a first time contributor? Perhaps with some guidance. I overall love the framework and am interested to at least try to get my hands dirty with this.

Alternatives

There are workarounds presented in the blogpost and why Luca thinks they are not ideal.

How is that different from having your own error type, implementing IntoResponse for it and using Result<_, MyAppError>?

This issue was linked to me by a friend, so I hope you don't mind if I pitch in.

I don't think axum would benefit significantly from adopting the decoupled error handling mechanism used in Pavex, especially considering the switching cost.

The error observer model, on the other hand, is interesting and I think the benefits would be real. The article @gyzerok linked goes into the details of what that entails.
I don't think it'd be possible to ship it as an additive feature though.

How is that different from having your own error type, implementing IntoResponse for it and using Result<_, MyAppError>?

I think what @gyzerok wants is a unified way to log and report errors. If MyAppError is only used for one or two handlers, then the error logging is likely coupled with certain handlers, if MyAppError is generic over all possible errors in an axum application, then there are shortcomings listed in the blog. And because of the use the tracing, root span for the request must be accessed as well.

Experienced users might have came up with their own solutions to this, but I do think as a framework axum could do better. I mean, to even spot the problem requires a little bit of knowledge about the internals of both axum and tracing. Currently it's easy for axum users to spam logs everywhere.