Consolidate error chain inspection with cause_ref#1671
Conversation
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]>
| /// 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() { |
There was a problem hiding this comment.
This was buggy! We never inspected error's type. The new tests check this case.
| 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)); | ||
| } |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
yeah that was my thought process as well.
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { |
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]>
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]>
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_byandcause_ref.These helpers are now tested.
Signed-off-by: Oliver Gould [email protected]