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

Early return inside middleware! macro #389

Open
mmacedoeu opened this issue Dec 7, 2016 · 3 comments
Open

Early return inside middleware! macro #389

mmacedoeu opened this issue Dec 7, 2016 · 3 comments

Comments

@mmacedoeu
Copy link

I need to return early if preconditions are not met, but tuple response is not accepted if I use return:

fn main() {
  let mut server = Nickel::new();
  server.post("/claim",
    middleware!{ |request, response|
      let condition : bool = try_with!(response, {handle_preconditions().map_err(|e| (StatusCode::BadRequest, e))});

     if !condition {
       return (StatusCode::PreconditionRequired, "invalid state".to_string()); // this is not compilling
       // expected type `std::result::Result<nickel::Action<nickel::Response<'mw, _>, //nickel::Response<'mw, _, hyper::net::Streaming>>, nickel::NickelError<'mw, _>>`
//    = note:    found type `(hyper::status::StatusCode, std::string::String)`
     }

      let good : bool = try_with!(response, {handle_processing().map_err(|e| (StatusCode::BadRequest, e))});

      if good {
         (StatusCode::Accepted, "Fine".to_string())
      } else {
         (StatusCode::NotAcceptable, "Not Fine".to_string())
      }

    });
    server.listen("127.0.0.1:6767").unwrap();
}

It is expecting a return of type std::result::Result<nickel::Action<nickel::Response<'mw, _>, nickel::Response<'mw, _, hyper::net::Streaming>>, nickel::NickelError<'mw, _>>

How can I early return ?

@mattlknight
Copy link

I'm not very good at offering advice, but im currently banging my head against Nickel.rs and it's macros.

I believe this might help you.

In your file, use
use nickel::MiddlewareResult;
and then for your early return use return response.send(put your stuff here);
Ex:
return response.send((StatusCode::Accepted, "Fine".to_string()));

@ghost
Copy link

ghost commented Jan 18, 2017

I guess this also should work:

return Err(From::from((
    response, (
        StatusCode::PreconditionRequired, 
        String::from("invalid state")
    )
)));

https://github.com/nickel-org/nickel.rs/blob/master/src/nickel_error.rs#L72

@jolhoeft
Copy link
Member

I figured this out while sorting out #399. Basically the middleware macro is somewhat fragile. It looks like it takes a closure, but is actually taking a block. The block must return something implementing Responder. Note that since it is a block, the return statement interacts with the macro expansion in unexpected ways. To make the original example work, you need to not use return, and instead nest the if statements:

fn main() {
    let mut server = Nickel::new();
    server.post("/claim", middleware!{ |request, response|
        let condition : bool = try_with!(response, {handle_preconditions().map_err(|e| (StatusCode::BadRequest, e))});
                                        
        if !condition {
            (StatusCode::PreconditionRequired, "invalid state".to_string())
        } else {            
            let good : bool = try_with!(response, {handle_processing().map_err(|e| (StatusCode::BadRequest, e))});
            
            if good {
                (StatusCode::Accepted, "Fine".to_string())
            } else {
                (StatusCode::NotAcceptable, "Not Fine".to_string())
            }
        }
    });
    server.listen("127.0.0.1:6767").unwrap();
}

jolhoeft added a commit to jolhoeft/nickel.rs that referenced this issue Nov 19, 2017
Fix the examples that were returning MiddlewareResults in the
middlware! macro. A couple could be changed to return a Responder, but
most needed to be reimplemented as seperate functions.

Updated the middleware! macro documentaion to note the limitations
from issues nickel-org#399 and nickel-org#389.
jolhoeft added a commit to jolhoeft/nickel.rs that referenced this issue Nov 19, 2017
Fix the examples that were returning MiddlewareResults in the
middlware! macro. A couple could be changed to return a Responder, but
most needed to be reimplemented as seperate functions.

Updated the middleware! macro documentaion to note the limitations
from issues nickel-org#399 and nickel-org#389.

Disable ssl testing in travis, which was broken in commit
8d5a7d0. Issue nickel-org#415 to track
our SSL plan.
jolhoeft added a commit to jolhoeft/nickel.rs that referenced this issue Nov 23, 2017
Fix the examples that were returning MiddlewareResults in the
middlware! macro. A couple could be changed to return a Responder, but
most needed to be reimplemented as seperate functions.

Updated the middleware! macro documentaion to note the limitations
from issues nickel-org#399 and nickel-org#389.

Disable ssl testing in travis, which was broken in commit
8d5a7d0. Issue nickel-org#415 to track
our SSL plan.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants