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

Rework middleware to receive Response directly, add optional errors to Response #570

Merged
merged 5 commits into from
Jul 9, 2020

Conversation

Fishrock123
Copy link
Member

@Fishrock123 Fishrock123 commented Jun 5, 2020

Rework middleware so that:

  • next.run().await always returns a Response.
  • middleware return of tide::Result is always transformed into a Response with error set.

Adds the following things to Response:

  • pub fn error(&self) -> Option<&Error>
  • pub fn downcast_error<E>(&self) -> Option<&E>
  • pub fn take_error(&mut self) -> Option<Error>
  • impl From<Error> for Response
  • impl From<crate::Result> for Response

An example of this being used for an error handling middleware is included at examples/error_handling.rs, and Jacob has transformed someone else's in #452 (comment).

Dependencies:

Note: Please let me rebase before merging

@jbr
Copy link
Member

jbr commented Jun 6, 2020

@Fishrock123 i added a commit at Fishrock123#1 that gets this pr compiling

@Fishrock123 Fishrock123 changed the title wip on response-optional-error Rework middleware to receive Response directly, add optional errors to Response Jun 9, 2020
@Fishrock123
Copy link
Member Author

Here is what this could enable in the future once the Try trait stabilizes: Fishrock123#2

@jbr jbr added blocked An issue that's blocked on upstream changes design Open design question enhancement New feature or request labels Jun 18, 2020
Copy link
Member

@yoshuawuyts yoshuawuyts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is looking really good! -- left a few nits; but this is def in the right direction. Thanks so much @Fishrock123!

src/response.rs Show resolved Hide resolved
src/route.rs Outdated Show resolved Hide resolved
src/router.rs Outdated Show resolved Hide resolved
.github/workflows/ci.yaml Outdated Show resolved Hide resolved
src/middleware.rs Outdated Show resolved Hide resolved
src/endpoint.rs Outdated Show resolved Hide resolved
src/route.rs Outdated Show resolved Hide resolved
tide::log::start();
let mut app = tide::new();

app.middleware(After(|mut res: Response| async move {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should After take both request and response? For example I might want to read a request headers and modify the response as appropriate. One example is taking the client request header from request and setting it to response header.

Copy link
Member

@jbr jbr Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately that's not possible currently with After. If you need access to the request and the response, you'll need to write a full middleware. It would be misleading for After to provide a request, because it would be a clone, and potentially the "real" request could have changed after the clone was made, but that would be obfuscated by the After.

@Fishrock123
Copy link
Member Author

Fishrock123 commented Jun 21, 2020

ci blocked due to #612

@Fishrock123 Fishrock123 force-pushed the new-http-types-errors branch 3 times, most recently from 7c9e426 to 9fd5722 Compare June 22, 2020 04:33
Fishrock123 added a commit to Fishrock123/tide that referenced this pull request Jun 22, 2020
This allows errors to be propogated through the Tide middleware stack
while still keeping an existing Response intact. Effectively allowing
headers, body, etc to be passed along with an Error; while also opening
up options for nicer error handling via `res.downcast_error<>` checking.

Also contains APIs for turning an Error into a Response via Into, and
taking the error from / setting an error on an existing Response.

This is a breaking change in that `next.run().await` within middleware
no longer returns a tide::Result but rather always returns a
tide::Response.

Thanks to Jacob Rothstein for helping me get this to compile!

PR-URL: http-rs#570
@Fishrock123 Fishrock123 marked this pull request as ready for review June 22, 2020 19:02
@Fishrock123
Copy link
Member Author

Fishrock123 commented Jun 22, 2020

I believe this is just waiting on downstream releases now. I've rebased the commits nicely.

examples/error_handling.rs Outdated Show resolved Hide resolved
examples/error_handling.rs Outdated Show resolved Hide resolved
src/response.rs Outdated Show resolved Hide resolved
src/response.rs Outdated Show resolved Hide resolved
src/server.rs Outdated Show resolved Hide resolved
Fishrock123 added a commit to Fishrock123/tide that referenced this pull request Jun 22, 2020
This allows errors to be propogated through the Tide middleware stack
while still keeping an existing Response intact. Effectively allowing
headers, body, etc to be passed along with an Error; while also opening
up options for nicer error handling via `res.downcast_error<>` checking.

Also contains APIs for turning an Error into a Response via Into, and
taking the error from / setting an error on an existing Response.

This is a breaking change in that `next.run().await` within middleware
no longer returns a tide::Result but rather always returns a
tide::Response.

Thanks to Jacob Rothstein for helping me get this to compile!

PR-URL: http-rs#570
Copy link
Member

@yoshuawuyts yoshuawuyts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last comment, but otherwise this is looking 💯

src/response.rs Outdated Show resolved Hide resolved
Fishrock123 added a commit to Fishrock123/tide that referenced this pull request Jun 25, 2020
@Fishrock123
Copy link
Member Author

Addressed that, removed From<Result> for Response.

Copy link
Collaborator

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach seems better for middleware. Thanks!

Copy link
Member

@yoshuawuyts yoshuawuyts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patch LGTM!

http-rs/http-types#191 however was recently reverted, and this patch needs to be updated to bring the error types into Tide itself. That should allow us to move off the git deps, and allow us to merge. Excited for this!

Fishrock123 added a commit to Fishrock123/tide that referenced this pull request Jul 7, 2020
This allows errors to be propagated through the Tide middleware stack
while still keeping an existing Response intact. Effectively allowing
headers, body, etc to be passed along with an Error; while also opening
up options for nicer error handling via `res.downcast_error<>` checking.

Also contains APIs for turning an Error into a Response via Into, and
taking the error from / setting an error on an existing Response.

This is a breaking change in that `next.run().await` within middleware
no longer returns a tide::Result but rather always returns a
tide::Response.

Thanks to Jacob Rothstein for helping me get this to compile!

PR-URL: http-rs#570
Fishrock123 added a commit to Fishrock123/tide that referenced this pull request Jul 7, 2020
This allows errors to be propagated through the Tide middleware stack
while still keeping an existing Response intact. Effectively allowing
headers, body, etc to be passed along with an Error; while also opening
up options for nicer error handling via `res.downcast_error<>` checking.

Also contains APIs for turning an Error into a Response via Into, and
taking the error from / setting an error on an existing Response.

This is a breaking change in that `next.run().await` within middleware
no longer returns a tide::Result but rather always returns a
tide::Response.

Thanks to Jacob Rothstein for helping me get this to compile!

PR-URL: http-rs#570
Makes use of the newly introduced error propgation from
`Response: add optional error storage` to show a nice and
flexible error handler middleware approach.

Related to http-rs#549
Makes use of the newly updated error propgation from
`Response: add optional error storage` for a more
informative error case in the log middleware.
This is probably never what a Tide user wants.

The developer of a server can use the log middleware, otherwise this presents a risk as it may point to potentially exploitable flaws.

Additionally, Tide can't completely aguarentee this will be in an expected format.
@Fishrock123
Copy link
Member Author

Rebased and pulled the reverted logic from http-types (http-rs/http-types#174) up into here. I believe this is ready to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked An issue that's blocked on upstream changes design Open design question enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants