warp: Unreasonably hard to recover internal errors from Rejection.
At present, for any custom recovery method, a user is forced to manually call Rejection::find
for every possible internal error if they want to be able to properly shuttle back a suitable response for internal errors as well as their own errors.
It would be incredibly useful if we could simply expose the internal status code for a rejection that it would otherwise assign when handling rejections using the default error handler. This unlocks more than enough (namely, being able to call StatusCode::canonical_reason
) as the hard work has already been mapping the known errors to a suitable HTTP status code.
Given that you actually deprecated/removed the ability to do this, can you add some color as to the why and could we talk about either bringing it back or some other solution that doesn’t involve a ton of boilerplate?
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 11
- Comments: 18 (4 by maintainers)
Just to add my 2c, I wanted to be able to return errors from a JSON based API in a standard JSON format of my own choosing to the user. I had to look through the warp source to see what errors to match on, and then wrote a macro to make my life a little easier doing this.
Its pretty horrible, and it means that if new errors are exposed in warp, I’ll not be handling them until I notice. A generic way to obtain the status code so that I can handle them as I wish would make things cleaner and more future proof.
For interest, here’s my current error handling code to turn errors into my standard shape:
I’ve attempted to create a simple HTTP basic auth filter but ran into this issue. I can implement a filter that checks against the
Authorization
header and returns one of two custom rejections (i.e. “missing authorization header” and “incorrect auth”). A recovery function is then used to return a proper response for those custom rejections.However, the issue here then forces me to return a different (500?) response for the known (built-in) rejections since I have no access to the reply machinery for
Rejection
.I thought perhaps to try using a wrapping filter instead, but the implementation of those seem entirely private.
Even if we fix this issue so that we can get at a response representation of
Rejection
, it still means that the transformation of a rejection to a proper response would still take place in a recovery function, which is something that makes using a filter that checks auth a bit unergonomic, as omitting the recovery function would get back, by default, 500 responses for the custom rejections.I might be way off base, though, and perhaps there’s a simple way to make an auth filter that plays nice with the built-in filters, but I’m currently at a loss as how to move forward.
Would having a function available that converts the
Rejection
into its defaulthttp::Response
be something you’re looking for? And then you can modify any headers and the body?Just offering that I have the same issue where I basically just want to marshal the rejection to a specific JSON structure without having to catch and handle all “standard” errors (after handling my custom ones). I think being able to access
status
andto_string
would be sufficient for my needs.@seanmonstar any progress on this? Not being able to extract the status codes from warp’s ‘known’ errors means you would have to either manually find all 16 known types to return the correct code or just blanket return a 500.
https://github.com/seanmonstar/warp/blob/fbbbc5b8377914463e4411ef6fc48bfd97d15a6d/examples/rejections.rs#L61 The above will return incorrect codes as the rejection is not passed along even thought the comment states it is.
I think conceptually that works? I guess either a
http::Response
orStatusCode
are suitable for handing back as the response, but I’m probably biased here in that I really only need the status code so I can get the canonical reason.Just to sort of rubber duck it out here, the difference would be something like…
vs
This is, of course, ignoring the customized structure/encoding, but I think it captures the spirit of what I’m proposing here. To my eyes, having to mutate/extract from a pre-baked response feels like extra work, although admittedly I suppose it’s just exposing the allocation/construction of the response that would still otherwise happen?
But you wish to tweak the response somehow beyond the default? So just returning
Err(rejection)
isn’t enough?