Skip to content

Commit 36b53cf

Browse files
committed
fix: name the failing endpoint in StatusError messages
StatusError::RequestFailed and ::HttpError are raised by both runtime_status (GET /v1/status) and is_ready (GET /v1/ready), but both displayed "Failed to get runtime status", which is misleading in a readiness probe. Carry the URL and name it in the message instead.
1 parent f3e62bb commit 36b53cf

1 file changed

Lines changed: 39 additions & 2 deletions

File tree

src/status.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,26 @@ pub enum StatusError {
2020
HttpNotConfigured,
2121

2222
/// HTTP request failed with an error response.
23-
#[snafu(display("Failed to get runtime status (HTTP {status_code}): {response_body}"))]
23+
///
24+
/// Raised by both [`SpiceClient::runtime_status`] and [`SpiceClient::is_ready`],
25+
/// so the message names the endpoint that failed rather than assuming either one.
26+
#[snafu(display("Failed to query {url} (HTTP {status_code}): {response_body}"))]
2427
RequestFailed {
28+
/// Endpoint that returned the error response.
29+
url: String,
2530
/// HTTP status code returned by the server.
2631
status_code: u16,
2732
/// Response body from the server.
2833
response_body: String,
2934
},
3035

3136
/// HTTP transport error.
32-
#[snafu(display("Failed to get runtime status: {message}"))]
37+
///
38+
/// Raised by both [`SpiceClient::runtime_status`] and [`SpiceClient::is_ready`].
39+
#[snafu(display("Failed to query {url}: {message}"))]
3340
HttpError {
41+
/// Endpoint that could not be reached.
42+
url: String,
3443
/// Description of the transport failure.
3544
message: String,
3645
},
@@ -126,6 +135,7 @@ impl QueryHttpClient {
126135
.send()
127136
.await
128137
.map_err(|e| StatusError::HttpError {
138+
url: url.clone(),
129139
message: e.to_string(),
130140
})?;
131141

@@ -136,6 +146,7 @@ impl QueryHttpClient {
136146
status_code => {
137147
let response_body = response.text().await.unwrap_or_default();
138148
Err(StatusError::RequestFailed {
149+
url,
139150
status_code,
140151
response_body,
141152
})
@@ -152,6 +163,7 @@ impl QueryHttpClient {
152163
.send()
153164
.await
154165
.map_err(|e| StatusError::HttpError {
166+
url: url.clone(),
155167
message: e.to_string(),
156168
})?;
157169

@@ -161,6 +173,7 @@ impl QueryHttpClient {
161173
status_code => {
162174
let response_body = response.text().await.unwrap_or_default();
163175
Err(StatusError::RequestFailed {
176+
url,
164177
status_code,
165178
response_body,
166179
})
@@ -229,4 +242,28 @@ mod tests {
229242
assert!(!details[1].is_ready());
230243
assert_eq!(details[2].endpoint, "N/A");
231244
}
245+
246+
#[test]
247+
fn request_errors_name_the_endpoint_that_failed() {
248+
// `RequestFailed`/`HttpError` are shared by `runtime_status` (/v1/status) and
249+
// `is_ready` (/v1/ready), so the message has to say which one was being queried.
250+
let request_failed = StatusError::RequestFailed {
251+
url: "http://localhost:8090/v1/ready".to_string(),
252+
status_code: 401,
253+
response_body: "unauthorized".to_string(),
254+
};
255+
assert_eq!(
256+
request_failed.to_string(),
257+
"Failed to query http://localhost:8090/v1/ready (HTTP 401): unauthorized"
258+
);
259+
260+
let http_error = StatusError::HttpError {
261+
url: "http://localhost:8090/v1/status".to_string(),
262+
message: "connection refused".to_string(),
263+
};
264+
assert_eq!(
265+
http_error.to_string(),
266+
"Failed to query http://localhost:8090/v1/status: connection refused"
267+
);
268+
}
232269
}

0 commit comments

Comments
 (0)