Skip to content

Consolidate error chain inspection with cause_ref#1671

Merged
olix0r merged 1 commit intomainfrom
ver/cause_ref
May 16, 2022
Merged

Consolidate error chain inspection with cause_ref#1671
olix0r merged 1 commit intomainfrom
ver/cause_ref

Conversation

@olix0r
Copy link
Member

@olix0r olix0r commented May 16, 2022

We have similar/redundant code that handles inspecting (boxed) errors to
determine whether they are caused by a given error type. This change
replaces the other methods for expecting with utility functions
is_caused_by and cause_ref.

These helpers are now tested.

Signed-off-by: Oliver Gould [email protected]

We have similar/redundant code that handles inspecting (boxed) errors to
determine whether they are caused by a given error type. This change
replaces the other methods for expecting with utility functions
`is_caused_by` and `cause_ref`.

These helpers are now tested.

Signed-off-by: Oliver Gould <[email protected]>
@olix0r olix0r requested a review from a team as a code owner May 16, 2022 19:22
Comment on lines -23 to -27
/// Determines if the provided error was caused by an `E` typed error.
pub fn caused_by<'e, E: std::error::Error + 'static>(
mut error: &'e (dyn std::error::Error + 'static),
) -> Option<&'e E> {
while let Some(src) = error.source() {
Copy link
Member Author

Choose a reason for hiding this comment

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

This was buggy! We never inspected error's type. The new tests check this case.

Copy link
Contributor

Choose a reason for hiding this comment

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

whoops!

Comment on lines -131 to 144
fn rescue(&self, error: Error) -> Result<errors::SyntheticHttpResponse> {
let cause = errors::root_cause(&*error);
if cause.is::<crate::policy::DeniedUnauthorized>() {
if let Some(cause) = errors::cause_ref::<crate::policy::DeniedUnauthorized>(&*error) {
return Ok(errors::SyntheticHttpResponse::permission_denied(cause));
}
if cause.is::<crate::GatewayDomainInvalid>() {
if let Some(cause) = errors::cause_ref::<crate::GatewayDomainInvalid>(&*error) {
return Ok(errors::SyntheticHttpResponse::not_found(cause));
}
if cause.is::<crate::GatewayIdentityRequired>() {
if let Some(cause) = errors::cause_ref::<crate::GatewayIdentityRequired>(&*error) {
return Ok(errors::SyntheticHttpResponse::unauthenticated(cause));
}
if cause.is::<crate::GatewayLoop>() {
if let Some(cause) = errors::cause_ref::<crate::GatewayLoop>(&*error) {
return Ok(errors::SyntheticHttpResponse::loop_detected(cause));
}
if cause.is::<errors::FailFastError>() {
if let Some(cause) = errors::cause_ref::<errors::FailFastError>(&*error) {
return Ok(errors::SyntheticHttpResponse::gateway_timeout(cause));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this does mean that we will now traverse the entire cause chain for every separate if condition, rather than doing it once to find the root cause and then testing that error's type. OTTOH, this code will now handle cases where the error of a desired type is not the ultimate root cause...although i believe all of these error types are always roots.

i don't know if the performance implications of iterating over the cause chain multiple times is really worth worrying about, but i wanted to point it out — i think having a single correct implementation of this is worth more than not traversing a couple nested causes a few more times, in any case.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah that was my thought process as well.

}

#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

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

<3

@olix0r olix0r merged commit 2100c9f into main May 16, 2022
@olix0r olix0r deleted the ver/cause_ref branch May 16, 2022 22:22
olix0r added a commit to linkerd/linkerd2 that referenced this pull request May 24, 2022
This release fixes a problem with HTTP/1.1 `CONNECT` requests. When a
server responds to a `CONNECT` request with `content-length` or
`transfer-encoding` headers (in violation of RFC 7231), the proxy must
actively strip these headers to avoid making the Hyper server fail the
response.

This release also fixes an issue with the way proxies discover control
plane components via DNS. When `SRV` records cannot be resolved, the
proxy would no not necessarily fall back to resolving `A` records. This
has been fixed.

Finally, the inbound proxy can now discover policies dynamically. Ports
that are configured in the `LINKERD2_PROXY_INBOUND_PORTS` are discovered
as the proxy starts up; but now the proxy will discover policies for
ports that are not in this list. The pod's default policy is used
initially, but once a policy is received from the control plane it is
used.

---

* build(deps): bump syn from 1.0.93 to 1.0.94 (linkerd/linkerd2-proxy#1664)
* build(deps): bump tj-actions/changed-files from 19 to 20 (linkerd/linkerd2-proxy#1665)
* build(deps): bump rustls from 0.20.4 to 0.20.5 (linkerd/linkerd2-proxy#1666)
* build(deps): bump ryu from 1.0.9 to 1.0.10 (linkerd/linkerd2-proxy#1667)
* build(deps): bump tokio-util from 0.7.1 to 0.7.2 (linkerd/linkerd2-proxy#1668)
* build(deps): bump itoa from 1.0.1 to 1.0.2 (linkerd/linkerd2-proxy#1669)
* build(deps): bump tonic from 0.7.1 to 0.7.2 (linkerd/linkerd2-proxy#1652)
* dns: Fall back to A record when SRV resolution fails (linkerd/linkerd2-proxy#1670)
* Consolidate error chain inspection with `cause_ref` (linkerd/linkerd2-proxy#1671)
* ci: change how warnings are denied on CI (linkerd/linkerd2-proxy#1662)
* build(deps): bump proc-macro2 from 1.0.38 to 1.0.39 (linkerd/linkerd2-proxy#1673)
* build(deps): bump libc from 0.2.125 to 0.2.126 (linkerd/linkerd2-proxy#1674)
* build(deps): bump syn from 1.0.94 to 1.0.95 (linkerd/linkerd2-proxy#1675)
* ci: Use the cargo-action-fmt setup action (linkerd/linkerd2-proxy#1672)
* opencensus: Include empty generated protobuf (linkerd/linkerd2-proxy#1676)
* build(deps): bump rustls from 0.20.5 to 0.20.6 (linkerd/linkerd2-proxy#1679)
* Revert "build(deps): bump socket2 from 0.4.4 to 0.4.5 (linkerd/linkerd2-proxy#1654)" (#1681)
* build(deps): bump EmbarkStudios/cargo-deny-action from 1.2.17 to 1.3.0 (linkerd/linkerd2-proxy#1678)
* build(deps): bump clang-sys from 1.3.1 to 1.3.2 (linkerd/linkerd2-proxy#1680)
* cache: generalize `Cache` into a key-value cache (linkerd/linkerd2-proxy#1683)
* build(deps): bump once_cell from 1.10.0 to 1.11.0 (linkerd/linkerd2-proxy#1687)
* build(deps): bump EmbarkStudios/cargo-deny-action from 1.3.0 to 1.3.1 (linkerd/linkerd2-proxy#1686)
* trace: add `/logs.json` endpoint to admin server (linkerd/linkerd2-proxy#1642)
* Dynamically discover policies for undocumented ports (linkerd/linkerd2-proxy#1677)
* Don't allow a policy to be used if `check_port_allowed` fails (linkerd/linkerd2-proxy#1689)
* ci: Simplify release workflow (linkerd/linkerd2-proxy#1690)
* build(deps): bump petgraph from 0.6.0 to 0.6.1 (linkerd/linkerd2-proxy#1696)
* build(deps): bump actions/upload-artifact from 3.0.0 to 3.1.0 (linkerd/linkerd2-proxy#1692)
* build(deps): bump tj-actions/changed-files from 20 to 20.1 (linkerd/linkerd2-proxy#1693)
* build(deps): bump http-body from 0.4.4 to 0.4.5 (linkerd/linkerd2-proxy#1694)
* build(deps): bump regex from 1.5.5 to 1.5.6 (linkerd/linkerd2-proxy#1695)
* build(deps): bump regex-syntax from 0.6.25 to 0.6.26 (linkerd/linkerd2-proxy#1697)
* http: Strip illegal headers from CONNECT responses (linkerd/linkerd2-proxy#1699)
* dev: Replace `Makefile` with `justfile` (linkerd/linkerd2-proxy#1691)

Signed-off-by: Oliver Gould <[email protected]>
olix0r added a commit to linkerd/linkerd2 that referenced this pull request May 24, 2022
This release fixes a problem with HTTP/1.1 `CONNECT` requests. When a
server responds to a `CONNECT` request with `content-length` or
`transfer-encoding` headers (in violation of RFC 7231), the proxy must
actively strip these headers to avoid making the Hyper server fail the
response.

This release also fixes an issue with the way proxies discover control
plane components via DNS. When `SRV` records cannot be resolved, the
proxy would no not necessarily fall back to resolving `A` records. This
has been fixed.

Finally, the inbound proxy can now discover policies dynamically. Ports
that are configured in the `LINKERD2_PROXY_INBOUND_PORTS` are discovered
as the proxy starts up; but now the proxy will discover policies for
ports that are not in this list. The pod's default policy is used
initially, but once a policy is received from the control plane it is
used.

---

* build(deps): bump syn from 1.0.93 to 1.0.94 (linkerd/linkerd2-proxy#1664)
* build(deps): bump tj-actions/changed-files from 19 to 20 (linkerd/linkerd2-proxy#1665)
* build(deps): bump rustls from 0.20.4 to 0.20.5 (linkerd/linkerd2-proxy#1666)
* build(deps): bump ryu from 1.0.9 to 1.0.10 (linkerd/linkerd2-proxy#1667)
* build(deps): bump tokio-util from 0.7.1 to 0.7.2 (linkerd/linkerd2-proxy#1668)
* build(deps): bump itoa from 1.0.1 to 1.0.2 (linkerd/linkerd2-proxy#1669)
* build(deps): bump tonic from 0.7.1 to 0.7.2 (linkerd/linkerd2-proxy#1652)
* dns: Fall back to A record when SRV resolution fails (linkerd/linkerd2-proxy#1670)
* Consolidate error chain inspection with `cause_ref` (linkerd/linkerd2-proxy#1671)
* ci: change how warnings are denied on CI (linkerd/linkerd2-proxy#1662)
* build(deps): bump proc-macro2 from 1.0.38 to 1.0.39 (linkerd/linkerd2-proxy#1673)
* build(deps): bump libc from 0.2.125 to 0.2.126 (linkerd/linkerd2-proxy#1674)
* build(deps): bump syn from 1.0.94 to 1.0.95 (linkerd/linkerd2-proxy#1675)
* ci: Use the cargo-action-fmt setup action (linkerd/linkerd2-proxy#1672)
* opencensus: Include empty generated protobuf (linkerd/linkerd2-proxy#1676)
* build(deps): bump rustls from 0.20.5 to 0.20.6 (linkerd/linkerd2-proxy#1679)
* Revert "build(deps): bump socket2 from 0.4.4 to 0.4.5 (linkerd/linkerd2-proxy#1654)" (#1681)
* build(deps): bump EmbarkStudios/cargo-deny-action from 1.2.17 to 1.3.0 (linkerd/linkerd2-proxy#1678)
* build(deps): bump clang-sys from 1.3.1 to 1.3.2 (linkerd/linkerd2-proxy#1680)
* cache: generalize `Cache` into a key-value cache (linkerd/linkerd2-proxy#1683)
* build(deps): bump once_cell from 1.10.0 to 1.11.0 (linkerd/linkerd2-proxy#1687)
* build(deps): bump EmbarkStudios/cargo-deny-action from 1.3.0 to 1.3.1 (linkerd/linkerd2-proxy#1686)
* trace: add `/logs.json` endpoint to admin server (linkerd/linkerd2-proxy#1642)
* Dynamically discover policies for undocumented ports (linkerd/linkerd2-proxy#1677)
* Don't allow a policy to be used if `check_port_allowed` fails (linkerd/linkerd2-proxy#1689)
* ci: Simplify release workflow (linkerd/linkerd2-proxy#1690)
* build(deps): bump petgraph from 0.6.0 to 0.6.1 (linkerd/linkerd2-proxy#1696)
* build(deps): bump actions/upload-artifact from 3.0.0 to 3.1.0 (linkerd/linkerd2-proxy#1692)
* build(deps): bump tj-actions/changed-files from 20 to 20.1 (linkerd/linkerd2-proxy#1693)
* build(deps): bump http-body from 0.4.4 to 0.4.5 (linkerd/linkerd2-proxy#1694)
* build(deps): bump regex from 1.5.5 to 1.5.6 (linkerd/linkerd2-proxy#1695)
* build(deps): bump regex-syntax from 0.6.25 to 0.6.26 (linkerd/linkerd2-proxy#1697)
* http: Strip illegal headers from CONNECT responses (linkerd/linkerd2-proxy#1699)
* dev: Replace `Makefile` with `justfile` (linkerd/linkerd2-proxy#1691)

Signed-off-by: Oliver Gould <[email protected]>
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

Successfully merging this pull request may close these issues.

2 participants