Comments (12)
I have been playing around with warp and have run into this as well. The warp::Reply
trait allows a number of different ways to create a reply. This allows for simple use cases (using only a string or number) and complex use cases that want to build up complex responses using http::Response
.
The warp::Rejection
type is a dead end in that it only accepts a reason code. There are use cases where I want to return a body along with the reason code and even other use cases where I want to set a Content-Type
header as well.
I think warp::Rejection
should to allow for an http::Response
or ReplySealed
should to be implemented for Result<impl warp::Reply, impl warp::Reply>
.
from warp.
I believe the intent with Rejection
is to be a very small error type that covers the most common errors. In the hypothetical 1.0 release, I think that the Reject
trait would be unsealed, and you'd have your custom error implement that.
from warp.
Proposal: Error reform
Current State
Reject
holds only a status Reason: u8
which can be composed with another rejection to determine final Filter
result. (as I understood after digging a code)
So Reject
usable for flow control during Filter
execution and lacks an error description which critical for debugging and ops. In many cases, an error cause just lost (for example https://github.com/seanmonstar/warp/blob/master/src/filters/fs.rs#L187)
Proposal
It would be better using same error handling mechanism as finch, (see https://github.com/finagle/finch/blob/master/core/src/main/scala/io/finch/EndpointResult.scala#L111-L128). Which means:
- Using separate enum variant which indicates that current filter's branch isn't matched.
- Fail fast, no error composition, trying next branch only if first returns
NotMatched
- An error keeps inside another enum variant
Reject
and Rejection
may be changed to:
pub enum Rejection {
// signals that current `Filter`'s branch is not valid and cannot be matched.
NotMatched,
// holds an internal error which maybe happens during filter execution or user handler's result
Err {
status: StatusCode,
err: Box<StdError + Send + 'static>
}
}
pub trait Reject {
fn status(&self) -> http::StatusCode;
fn into_response(&self) -> ::reply::Response;
fn cause(&self) -> Option<StdError + Send + 'static>;
fn is_matched(&self) -> bool;
}
impl Reject for Rejection { ... }
from warp.
The current rejection system in warp is a lot closer to that of Akka's rejections, which specifically allows for other routes to be tried even if there is a rejection that isn't equivalent to NotMatched/NotFound.
This allows for things predicates to check for things like query parameters or headers, and if one is wrong, it may wish to tell the user it's a 400 Bad Request
, not 404 Not Found
, while still allowing an alternative route to notice and instead serve a response.
from warp.
Then Rejection signature may be changed to
struct Rejection {
reason: Reason,
err: Box<StdError + Send + 'static>
}
it still able to combine status codes, and also contains an error message. Combine would be check reason and use an error from the most important instance. eg
Rejection(NOT_FOUND, err1) + Rejection(SERVER_ERROR, err2) => Rejection(NOT_FOUND + SERVER_ERROR, err2)
from warp.
This is also very much a requirement for us - I note that Rejection
has a with
method where the rejection can be given a boxed error. But alas, does not actually get put into the body.
Of course, one can by-pass Rejection
and return Reply
using Response::Builder
. But then the problem is that there are potentially two types being returned matching a impl Reply
. In Hyper there is at least Either, and I can't box that Reply...
from warp.
The workaround I stumbled on, was that after using with
, the Rejection
could be serialized out to JSON in a recover()
handler. Not too shabby...
from warp.
@stevedonovan see #94,
I've improved an error handling for custom errors, you could turn a Rejection into JSON response without boilerplate code.
from warp.
That feels like a very good extension to Rejection, thanks! Looking forward to the merge. In this case, I'm generating warp boilerplate automatically anyway, so it was not too awkward, but this is definitely an ergonomic improvement.
from warp.
The improvements in #94 are part of 0.1.5, so I'm going to close this up.
from warp.
Is this still possible to do with the latest version of Warp (0.2.1), if so could you please update the error/rejection examples? I am trying to return the exact reason for the error in JSON format, however I can't access the "reason" field from "Rejection".
from warp.
@ZakisM You can just call .to_string()
on the cause, like this
if let Some(e) = err.find::<warp::filters::body::BodyDeserializeError>() {
code = http::StatusCode::BAD_REQUEST;
message = e.to_string();
}
from warp.
Related Issues (20)
- Feature request: Fallible extractor filter
- Clarify API docs around multipart forms HOT 2
- Feature request: More customization points in tracing HOT 2
- EC Private key support HOT 1
- Make `Option<F>` a filter when F is a filter
- 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 4
- key contains no private key while using ecc key HOT 1
- integrate with monoio
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.