@@ -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