Coder Social home page Coder Social logo

Comments (12)

hjr3 avatar hjr3 commented on May 5, 2024 4

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.

kamalmarhubi avatar kamalmarhubi commented on May 5, 2024

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.

dmexe avatar dmexe commented on May 5, 2024

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 Filterexecution 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:

  1. Using separate enum variant which indicates that current filter's branch isn't matched.
  2. Fail fast, no error composition, trying next branch only if first returns NotMatched
  3. 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.

seanmonstar avatar seanmonstar commented on May 5, 2024

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.

dmexe avatar dmexe commented on May 5, 2024

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.

stevedonovan avatar stevedonovan commented on May 5, 2024

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.

stevedonovan avatar stevedonovan commented on May 5, 2024

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.

dmexe avatar dmexe commented on May 5, 2024

@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.

stevedonovan avatar stevedonovan commented on May 5, 2024

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.

seanmonstar avatar seanmonstar commented on May 5, 2024

The improvements in #94 are part of 0.1.5, so I'm going to close this up.

from warp.

ZakisM avatar ZakisM commented on May 5, 2024

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.

danstewart avatar danstewart commented on May 5, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.