Skip to content
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

Endpoint handler cannot programmatically defer to another handler for the same endpoint #609

Closed
pie-flavor opened this issue Apr 15, 2018 · 2 comments
Labels
request Request for new functionality

Comments

@pie-flavor
Copy link

Right now there's no way to forward to another handler if the parameters parsed, but didn't fit. A great example of this would be with FlashMessage - it must be wrapped in an Option because otherwise it 400s, but what if you want to defer instead of erroring when it's absent?

My thought is that Forward would become a new Responder, forwarding control to the next handler. It could also contain a Status for what code should be returned if it turns out that there is nothing to forward to. It'd be constructed via ::new which defaults this error to 404, or ::with_err which takes the Status. Incidentally, this'd solve the problem for FlashMessage needing to fail hard in the first place to change the error code.

@jebrosen
Copy link
Collaborator

For this particular case, something similar to the following request guard should address the FlashMessage aspect of your question. It passes cargo check, otherwise completely untested:

use rocket::request::FlashMessage;
pub struct FlashOrForward(FlashMessage);

impl ::std::ops::Deref for FlashOrForward {
    type Target = FlashMessage;
    fn deref(&self) -> &FlashMessage { &self.0 }
}

impl FromRequest<'a, 'r> for FlashOrForward {
    type Error = ();

    fn from_request(request: &Request) -> request::Outcome<Self, Self::Error> {
        match FlashMessage::from_request(request) {
            Outcome::Success(f) => Outcome::Success(FlashOrForward(f)),
            Outcome::Forward(_) | Outcome::Failure(_) => Outcome::Forward(()),
        }
    }
}

This approach can also do some other things you suggested, such as changing the error code, but it may not be as powerful as your hypothetical Forward Responder in as many situations.

@SergioBenitez SergioBenitez added the request Request for new functionality label Apr 16, 2018
@SergioBenitez
Copy link
Member

In general, I have not encountered a need for this - neither myself nor via support requests - that cannot be elegantly handled by a request guard. As such, I am closing this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request Request for new functionality
Projects
None yet
Development

No branches or pull requests

3 participants