Skip to content

Commit bdb5b84

Browse files
fix(health): use ordered slice for error pattern matching
The formatErrorSummary function used a map for error pattern matching, but Go map iteration order is non-deterministic. This caused flaky test failures when error messages matched multiple patterns (e.g., 'dial tcp: no such host' matches both 'dial tcp' and 'no such host'). Changed to an ordered slice where more specific patterns (like 'no such host') are checked before generic ones (like 'dial tcp'). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2acc7ae commit bdb5b84

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

internal/health/calculator.go

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -204,25 +204,33 @@ func formatErrorSummary(lastError string) string {
204204
return "Connection error"
205205
}
206206

207-
// Common error patterns to friendly messages
208-
errorMappings := map[string]string{
209-
"connection refused": "Connection refused",
210-
"no such host": "Host not found",
211-
"connection reset": "Connection reset",
212-
"timeout": "Connection timeout",
213-
"EOF": "Connection closed",
214-
"authentication failed": "Authentication failed",
215-
"unauthorized": "Unauthorized",
216-
"forbidden": "Access forbidden",
217-
"oauth": "OAuth error",
218-
"certificate": "Certificate error",
219-
"dial tcp": "Cannot connect",
207+
// Common error patterns to friendly messages.
208+
// Order matters: more specific patterns must come before generic ones.
209+
// For example, "no such host" must be checked before "dial tcp" since
210+
// DNS errors often appear as "dial tcp: no such host".
211+
errorMappings := []struct {
212+
pattern string
213+
friendly string
214+
}{
215+
// Specific patterns first
216+
{"no such host", "Host not found"},
217+
{"connection refused", "Connection refused"},
218+
{"connection reset", "Connection reset"},
219+
{"timeout", "Connection timeout"},
220+
{"EOF", "Connection closed"},
221+
{"authentication failed", "Authentication failed"},
222+
{"unauthorized", "Unauthorized"},
223+
{"forbidden", "Access forbidden"},
224+
{"oauth", "OAuth error"},
225+
{"certificate", "Certificate error"},
226+
// Generic patterns last
227+
{"dial tcp", "Cannot connect"},
220228
}
221229

222-
// Check for known patterns
223-
for pattern, friendly := range errorMappings {
224-
if containsIgnoreCase(lastError, pattern) {
225-
return friendly
230+
// Check for known patterns (in order)
231+
for _, mapping := range errorMappings {
232+
if containsIgnoreCase(lastError, mapping.pattern) {
233+
return mapping.friendly
226234
}
227235
}
228236

0 commit comments

Comments
 (0)