Skip to content

Commit fb4dfe9

Browse files
authored
fix(canopy): flatten miette error chain when reporting failures (#75)
2 parents ff0e507 + 450ea97 commit fb4dfe9

3 files changed

Lines changed: 20 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jiff = { version = "0.2.25", features = ["serde"] }
1818
k8s-openapi = { version = "0.27.1", features = ["latest", "schemars"] }
1919
kube = { version = "3.1.0", default-features = false, features = ["runtime", "derive", "client", "rustls-tls", "ws"] }
2020
kube_quantity = "0.9.0"
21+
miette = "7.6.0"
2122
mimalloc = { version = "0.1", default-features = false }
2223
prometheus = "0.14.0"
2324
rand = "0.10.1"

src/canopy.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl Client {
103103
self.inner
104104
.restore_capabilities(&self.base_url, intents)
105105
.await
106-
.map_err(|err| Error::Canopy(format!("restore_capabilities: {err}")))
106+
.map_err(|err| Error::Canopy(format!("restore_capabilities: {}", chain(&err))))
107107
}
108108

109109
/// Fetch the consumer's desired-state worklist. Each entry is one
@@ -112,7 +112,7 @@ impl Client {
112112
self.inner
113113
.restore_worklist(&self.base_url)
114114
.await
115-
.map_err(|err| Error::Canopy(format!("restore_worklist: {err}")))
115+
.map_err(|err| Error::Canopy(format!("restore_worklist: {}", chain(&err))))
116116
}
117117

118118
/// Fetch short-lived read-only STS creds plus the repo password for a
@@ -127,7 +127,8 @@ impl Client {
127127
.await
128128
.map_err(|err| {
129129
Error::Canopy(format!(
130-
"restore_credentials({backup_type}, {group}): {err}"
130+
"restore_credentials({backup_type}, {group}): {}",
131+
chain(&err)
131132
))
132133
})
133134
}
@@ -137,7 +138,7 @@ impl Client {
137138
self.inner
138139
.restore_verification(&self.base_url, report)
139140
.await
140-
.map_err(|err| Error::Canopy(format!("restore_verification: {err}")))
141+
.map_err(|err| Error::Canopy(format!("restore_verification: {}", chain(&err))))
141142
}
142143

143144
/// Direct access to the public-mTLS base URL the client is configured
@@ -148,6 +149,19 @@ impl Client {
148149
}
149150
}
150151

152+
/// Flatten a `miette::Report` (bestool-canopy's error type) to a single
153+
/// `outer: inner: root` line by walking its source chain. bestool wraps
154+
/// its errors with `.wrap_err(...)` which layers context around the
155+
/// underlying reqwest / io error, and plain `Display` on the report
156+
/// only shows the outermost message — losing the actually diagnostic
157+
/// bit.
158+
fn chain(err: &miette::Report) -> String {
159+
err.chain()
160+
.map(|e| e.to_string())
161+
.collect::<Vec<_>>()
162+
.join(": ")
163+
}
164+
151165
/// Re-export the wire types pgro consumes verbatim from `bestool-canopy`.
152166
pub use bestool_canopy::{
153167
BackupCredentials as Credentials, Outcome, RestoreCredentials as CredsResponse,

0 commit comments

Comments
 (0)