Comments (18)
Presumably there should be:
warp::reject::unmatched()
- this filter didn't match but it could be valid for a different filter.warp::reject::not_found()
- the request was definitely intended for this filter but the requested resource was not found.
from warp.
maybe there could be a way to cut backtracking? ie, if we know we got to a specific prefix or argument, we're in the right route, and should return the error from this route
from warp.
My vote is for some way to cut the backtracking. Currently I'm using the approach proposed by @blm768 , but as he mentioned it's not quite ergonomic.
IMHO any reject provided by a user's code should by default stop the processing and just return the rejection, and probably it's not a too bad idea to have a special reject like reject::try_something_different()
(bad naming, but I hope you'll get the point) that should be returned by the combinators to go for furthers or
s.
from warp.
+1 for this behavior being unexpected.
As an example, in the todos example when you build the filters which all contain paths under /todos
:
Line 93 in f334f51
if you add the lines
let req = warp::test::request().path("/");
assert_eq!(req.reply(&api).status(), 404);
the assertion fails with 405 even though you'd expect to get a 404 since we have no routes on /
The workaround is as you mentioned above, you can add an .or_else(|_| Err(warp::reject::not_found()));
to the end of the filter and the assertion will pass. However, now you don't get proper 405 errors when doing get requests on post-only paths.
I don't know what the best way to solve this in general is though.
from warp.
In principle, if you want a particular error to override all others, you can return an Ok(http::Response)
with that error code. Maybe not the most ergonomic way to do it, but it's accepting the mapping of route to resource and then rejecting the request, so it kind of makes sense in an abstract way.
Alternatively, in this case, you could probably move the get2()
farther down the chain.
from warp.
I think so: my original gist was oversimplified for that case. I imagine putting get_dog
last in routes
would technically fix it, since a blanket Ok(404) response from a recover handler prevents or() from looking for more routes. The simplest design might be just building a response in get_dog
that handles both success and the error case for that lookup. Another alternative that should work is using a custom rejection type, and recovering specifically from that. I updated this with both of those alternatives:
https://gist.github.com/luke-brown/fbaa1392964befd9a285ca310f0b270a
That second option probably looks more complicated than the "inline" option--here it's certainly a lot more code--but so far I've found that using custom rejection types makes handling complex handlers easy to reject early from.
from warp.
Considering the comments from @Timmmm, I guess we should distinguish parse errors and application errors.
from warp.
Thanks so much for your help on this!
from warp.
No, you aren't wrong in thinking that. Currently, the rejections in warp collect and the highest priority one is chosen to render as a response. It's assumed that Not Found is the lowest priority, so the method rejection from the post plus the not found rejection you create means the 405 is shown.
The priority of these could maybe need adjustment.
from warp.
Can you explain how I could return such a response from a header filter? I think that is not possible right now if I am not mistaken?
from warp.
Can you explain how I could return such a response from a header filter?
You could make use of Filter::recover
to alter the rejection, or Filter::or_else
can be useful to provide a "default" value overriding any rejection.
from warp.
There's an example to customize errors as described by @blm768 for anyone interested: examples/errors.rs
from warp.
What do other's think about the need for context-specific rejection payload? I still see no way to do that with the rejection design as-is. Or I am missing something.
My use case is 401 Unauthorized, where it is usually only known in that specific route, what exactly to return as Challenge parameters. Another use case would be HTTP Problems (https://tools.ietf.org/html/rfc7807).
Thoughts?
from warp.
Is there a recommended way to handle this case now? For example, I have a GET /dog/{id}
route that needs to return JSON when a matching dog is found and return a 404 when it is now. I have not been able to find a way to accomplish this.
from warp.
With the caveat that I'm new here and am certainly not authoritative, for what it's worth I've been able to address these issues by using what I think of as route-specific recover() handlers. Here's my interpretation of a solution to what you're describing, in context of the original example above:
https://gist.github.com/luke-brown/fbaa1392964befd9a285ca310f0b270a
That returns a 404 instead of a 405 when it doesn't match (randomized there).
from warp.
Thanks! I think warp should support an easier way to do this, but at least it works.
Somehow my POST /dog
route stopped working and I now get a 404. Can you spot why?
https://github.com/mvolkmann/rust-rest/blob/c7627eca2f66def33c5a9741c333c200d7e8bdda/warp/src/main.rs#L80
from warp.
I wonder if 404 could have two rejections. A publicly exposed one with a higher priority and one that is the catch all with lowest priority. That may help solve the issue here.
from warp.
Not happy with that as well. Really would like to have better return code without much workarounds 🙂
My workaround was to create custom rejection for this non-interceptable "Not Found" case: https://gist.github.com/meredian/9dff0dc056fc4c3e61252576ae86a41b
from warp.
Related Issues (20)
- Feature request: `warp::make_service()` or `warp::service_with_addr()`
- CVE-2023-43669/GHSA-9mcr-873m-xcxp: tungstenite <= 0.20.0 DoS vulnerability HOT 1
- [feature request] [low prio] Non-Metal fallback option HOT 2
- SSE gives up on Streams that return Pending HOT 3
- Server::run should return ! (never type)
- Default OS / self signed certificate without create it HOT 1
- websocket disconnect (code: 1006, reason: "") HOT 2
- Add `rust-version` into `Cargo.toml` HOT 1
- Error `connection closed before message completed` after 60s HOT 2
- Websocket connection closes immediately, but not with firefox HOT 4
- Navigation between panes using vim commands HOT 1
- examples/tls/cert.pem has expired
- Upgrade to hyper v1 HOT 6
- key contains no private key while using ecc key HOT 1
- integrate with monoio
- HELP: filters inside .then never get executed HOT 1
- Chinese input method following error in notebook HOT 2
- Graceful shutdown hangs when I use a Chromium based browser HOT 1
- Sending a JSON post with a string or bytes that contain the words <meta> causes a 403 HOT 5
- Not found error translate to method not allowed when there is route with method is at the start of the route
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from warp.