refactor(client): make managed failure classification exhaustive
classify_client_error now matches every ClientError variant explicitly, so a new variant fails to compile here until its real classification is chosen. NoTokioRuntime classifies as InvalidState and DatagramLengthMismatch as Socket; ManagedTargetFailureKind::Other survives only as a deliberate category with no default path into it. ManagedTargetFailurePhase and ManagedTargetFailureKind gain controlled Display impls, and the CLI client/TUI failure diagnostics use them instead of leaking Debug enum spelling into user-facing text.
This commit is contained in:
1 parent
90c04b6569
commit
e3003c348f
3 files changed
+279
-13
No files matched your search
@@ -277,13 +277,13 @@ fn target_failure_messages(target: &ManagedTargetOutcome) -> Vec<String> {
|
||||
let mut messages = Vec::with_capacity(2);
|
||||
if let ManagedTargetEndReason::Failed(failure) = &target.end_reason {
|
||||
messages.push(format!(
|
||||
"irtt-rs: target {} failed ({:?} {:?}): {}",
|
||||
"irtt-rs: target {} failed ({} {}): {}",
|
||||
target.target.id, failure.phase, failure.kind, failure.message
|
||||
));
|
||||
}
|
||||
if let Some(failure) = &target.cleanup_failure {
|
||||
messages.push(format!(
|
||||
"irtt-rs: target {} cleanup failed ({:?} {:?}): {}",
|
||||
"irtt-rs: target {} cleanup failed ({} {}): {}",
|
||||
target.target.id, failure.phase, failure.kind, failure.message
|
||||
));
|
||||
}
|
||||
@@ -480,8 +480,8 @@ mod tests {
|
||||
assert_eq!(
|
||||
target_failure_messages(&target),
|
||||
[
|
||||
"irtt-rs: target edge failed (Receiving Protocol): primary failure",
|
||||
"irtt-rs: target edge cleanup failed (Closing Socket): cleanup failure",
|
||||
"irtt-rs: target edge failed (receiving protocol): primary failure",
|
||||
"irtt-rs: target edge cleanup failed (closing socket): cleanup failure",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ impl TuiState {
|
||||
(TargetStatus::Replaced, "target replaced".to_owned(), None)
|
||||
}
|
||||
ManagedTargetEndReason::Failed(failure) => {
|
||||
let message = format!("{:?}: {}", failure.kind, failure.message);
|
||||
let message = format!("{}: {}", failure.kind, failure.message);
|
||||
(
|
||||
TargetStatus::Failed,
|
||||
format!("target failed: {message}"),
|
||||
@@ -205,7 +205,7 @@ impl TuiState {
|
||||
|
||||
let cleanup_warning = outcome.cleanup_failure.as_ref().map(|failure| {
|
||||
format!(
|
||||
"cleanup failed ({:?} {:?}): {}",
|
||||
"cleanup failed ({} {}): {}",
|
||||
failure.phase, failure.kind, failure.message
|
||||
)
|
||||
});
|
||||
@@ -2430,7 +2430,7 @@ mod tests {
|
||||
assert!(state.targets[1]
|
||||
.last_warning
|
||||
.as_deref()
|
||||
.is_some_and(|warning| warning.contains("Timeout")));
|
||||
.is_some_and(|warning| warning.contains("timeout")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2474,11 +2474,11 @@ mod tests {
|
||||
assert!(state.targets[0]
|
||||
.last_warning
|
||||
.as_deref()
|
||||
.is_some_and(|warning| warning.contains("cleanup failed (Closing Socket)")));
|
||||
.is_some_and(|warning| warning.contains("cleanup failed (closing socket)")));
|
||||
assert!(state
|
||||
.recent_events
|
||||
.iter()
|
||||
.any(|event| event.contains("cleanup failed (Closing Socket)")));
|
||||
.any(|event| event.contains("cleanup failed (closing socket)")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2509,11 +2509,11 @@ mod tests {
|
||||
assert!(state
|
||||
.recent_events
|
||||
.iter()
|
||||
.any(|event| event.contains("target failed: Protocol: primary failure")));
|
||||
.any(|event| event.contains("target failed: protocol: primary failure")));
|
||||
assert!(state
|
||||
.recent_events
|
||||
.iter()
|
||||
.any(|event| event.contains("cleanup failed (Closing Socket): cleanup failure")));
|
||||
.any(|event| event.contains("cleanup failed (closing socket): cleanup failure")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user