-
-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved rejections #712
Comments
For context, this is the way that I found to handle this case: let login = warp::post()
.and(warp::path!("api"/"login"))
.and(warp::body::json())
.and_then(|credentials: Credentials| async {
Ok(match login(credentials).await {
Ok(session) => warp::reply::json(&session).into_response(),
Err(status) => warp::reply::with_status("", status).into_response(),
}) as Result<warp::reply::Response, core::convert::Infallible>
}); There is a lot of boilerplate here that ought to be handled by So actually returning an error from a My current proposal would be to remove the |
It has been brought up multiple times, but I that also likely means the design is missing something. It might need to be easier to use rejections and stuff, but it also is the case that people see rejections and assume that all errors should be turned into rejections. That shouldn't be the case, though. Rejections are meant to say "this filter didn't accept the request, maybe another can." So things like I've seen it suggested the idea of "fatal" rejections, that don't try other filters. But I don't know... I don't yet know the best answer. |
I am glad to read this comment and wonder if I got the Rejection tool the other way around :-) I basically use Rejections to inject poison into a wrong request (e.g. wrong auth token, missing header, etc.) before any business logic kicks in, then get the request through all the remaining filters and be handled by a |
ah! I was also not aware of this, in my case what I have been previously doing is wrapping third party library errors in project ones eg: The issue i see with transforming third party library errors into |
The rejection system makes sense for built-in and custom filters, but for the final handler, e.g. some I hope @seanmonstar you can either take the time to re-think/extend this, or invite the community to come up with something for 0.3 and trust the kids to do the right thing :) |
FWIW, my suggestion is:
where The error is automatically converted into an This allows nice handler implementations, while the rejection can still be centrally recovered to convert to an error reply, together with 404's and such. |
I also assumed that way. Maybe this explanation should be added to the documentation? |
Some notes from Discord yesterday, hopefully to continue here:
|
Hm. Reading this thread gave me the idea that maybe a nice way of handling errors (not rejection) would be to |
You can't impl Reply (from warp) for Result (from std) in your lib due to
coherence rules.
…On Thu, Nov 5, 2020 at 4:23 PM Rasmus Kaj ***@***.***> wrote:
Hm. Reading this thread gave me the idea that maybe a nice way of handling
errors (not rejection) would be to impl Reply for Result<Response,
MyError>. Then *my* code can handle *my* errors, while fitting nicely
into the interface provided by warp. I'll do some experimentation on this.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#712 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABN2XOU73YR7NTGEWN55GTSOKRLRANCNFSM4RU7TBDQ>
.
|
Correct. I just found out that having my own type as an error type is not enough to impl a trait on Result. There is an Maybe warp should provide |
I thik PR #458 (which has been around since February) implements my suggestion better than my PR. |
I find the documentation very hard to read, because a lot of the code is hidden and not documented. For example, the Implementing Maybe it would be better if warp explicitly implemented a enum FilterResult<T> {
Ok(T),
Rejection(Rejection),
} Then it would be clear that this is not an error. Filter functions could then return some |
For certain types of errors, I want a 500 code and a log message. For other types of errors, I want to try a different filter. Handling this inside a enum Result<T, E> {
Ok(T),
Err(E),
Rej(Rejection)
}
enum Error<E> {
Custom(E),
Rejection(Rejection)
}
enum Result<T, E> {
Ok(T),
Err(Error<E>)
} I don't know. Maybe my silly ideas will inspire a more experienced rustacean. I'm just hoping that someone can figure this out! 😄 |
The way I see it, the And the nice way of doing that would be to return an Error that is not a rejection but instead treated as a reply, as per #458. Also, the way I see it, having a three-state special result, that may contain an Error or a Rejection would not be really helpful, as the operation should be in one of two modes: Either we are still resolving the route, in which case we need a |
@kaj The missing piece of the puzzle for me (which I discovered after writing the above comment) was |
Yes, that makes it possible to do explicit early-return of error replies, which is kind of nice. But #458 (I keep repeating that PR number) would make it possible to do that early return with the standard |
@Kerndog73, I've (accidently, thanks intellisense) found that calling |
I've recently run into ergonomic issues with the warp rejection handling as well. I'm writing a single page application with API handlers. I need to make sure all rejections in the API routes get turned into replies otherwise it will fall back to the SPA routes. I'm also using custom errors as rejections, but the ergonomic issue would apply even without it. That would be because I need to turn the warp filter rejections into replies as well. For example, missing header or body deserialize rejections. Writing a custom rejection handler is currently not very ergonomic - I think exposing the warp default rejection reply handler would be an easy win here. The code I want to write looks like this: In error.rs:
In main.rs:
Edit: I realized that what I'm looking for is already described here #751 (comment) |
I get the impression that the rejection system in this crate ought to be severely refactored. The rejections example does not show a simple way of handling functions which return
Results
:which is the standard way of handling Errors in Rust. The suggested way of handling this seems to be to
Reject for LoginError
(which requires me to own theLoginError
type)recover
after the handling filter with a "rejection handler" function, which converts rejections into aReply
type which can be sent by warpThis causes a lot of cognitive and syntactic overhead, and I think the crate would benefit a lot from a refactor like this.
The text was updated successfully, but these errors were encountered: