@@ -12,23 +12,56 @@ struct HealthResponse {
1212 error : Option < String > ,
1313}
1414
15- fn fetch_health ( api : & ApiClient , connection_id : & str , show_spinner : bool ) -> HealthResponse {
15+ /// Result of a best-effort health check. Either the endpoint responded with a
16+ /// parseable body, or it did not — in which case we record why and keep going.
17+ enum HealthStatus {
18+ Available ( HealthResponse ) ,
19+ Unavailable ( String ) ,
20+ }
21+
22+ impl HealthStatus {
23+ fn is_confirmed_unhealthy ( & self ) -> bool {
24+ matches ! ( self , HealthStatus :: Available ( h) if !h. healthy)
25+ }
26+ }
27+
28+ impl Serialize for HealthStatus {
29+ fn serialize < S : serde:: Serializer > ( & self , ser : S ) -> Result < S :: Ok , S :: Error > {
30+ match self {
31+ HealthStatus :: Available ( h) => h. serialize ( ser) ,
32+ HealthStatus :: Unavailable ( _) => ser. serialize_none ( ) ,
33+ }
34+ }
35+ }
36+
37+ fn fetch_health ( api : & ApiClient , connection_id : & str , show_spinner : bool ) -> HealthStatus {
1638 let spinner = show_spinner. then ( || crate :: util:: spinner ( "Checking connection health..." ) ) ;
17- let health : HealthResponse = api. get ( & format ! ( "/connections/{connection_id}/health" ) ) ;
39+ let ( status , body ) = api. get_raw ( & format ! ( "/connections/{connection_id}/health" ) ) ;
1840 if let Some ( s) = spinner { s. finish_and_clear ( ) ; }
19- health
41+
42+ if !status. is_success ( ) {
43+ return HealthStatus :: Unavailable ( crate :: util:: api_error ( body) ) ;
44+ }
45+ match serde_json:: from_str :: < HealthResponse > ( & body) {
46+ Ok ( h) => HealthStatus :: Available ( h) ,
47+ Err ( e) => HealthStatus :: Unavailable ( format ! ( "parse error: {e}" ) ) ,
48+ }
2049}
2150
22- fn format_health ( health : & HealthResponse ) -> String {
51+ fn format_health ( health : & HealthStatus ) -> String {
2352 use crossterm:: style:: Stylize ;
24- if health. healthy {
25- match health . latency_ms {
53+ match health {
54+ HealthStatus :: Available ( h ) if h . healthy => match h . latency_ms {
2655 Some ( ms) => format ! ( "{} {}" , "healthy" . green( ) , format!( "({ms}ms)" ) . dark_grey( ) ) ,
2756 None => "healthy" . green ( ) . to_string ( ) ,
57+ } ,
58+ HealthStatus :: Available ( h) => {
59+ let err = h. error . as_deref ( ) . unwrap_or ( "unknown error" ) ;
60+ format ! ( "{} — {}" , "unhealthy" . red( ) , err)
61+ }
62+ HealthStatus :: Unavailable ( err) => {
63+ format ! ( "{} — {}" , "unavailable" . yellow( ) , err)
2864 }
29- } else {
30- let err = health. error . as_deref ( ) . unwrap_or ( "unknown error" ) ;
31- format ! ( "{} — {}" , "unhealthy" . red( ) , err)
3265 }
3366}
3467
@@ -260,7 +293,7 @@ pub fn create(
260293 _ => unreachable ! ( ) ,
261294 }
262295
263- if ! health. healthy {
296+ if health. is_confirmed_unhealthy ( ) {
264297 std:: process:: exit ( 1 ) ;
265298 }
266299}
0 commit comments