MCPcopy
hub / github.com/keploy/keploy / classifyUpstreamError

Function classifyUpstreamError

pkg/agent/proxy/integrations/http/upstream_error.go:45–85  ·  view source on GitHub ↗

classifyUpstreamError maps a raw network error into the (statusCode, reasonPhrase, marker-line) tuple used by synthesizeUpstreamErrorResponse. - err == nil (unexpected, but handled) -> 502 Bad Gateway (generic marker) - context.DeadlineExceeded / net.Error.Timeout() -> 504 Gateway Timeout

(err error)

Source from the content-addressed store, hash-verified

43// line is inlined into the body AND emitted as a response header so
44// downstream diff tooling (and humans) can grep for it in recorded YAML.
45func classifyUpstreamError(err error) (status int, reason, marker string) {
46 if err == nil {
47 // Don't classify nil as a timeout — that would mislabel any
48 // synthesized response whose caller forgot to pass the underlying
49 // error, and poison downstream timeout analysis. Use the generic
50 // 502 marker instead.
51 return 502, "Bad Gateway", UpstreamGenericMarker
52 }
53
54 // Timeouts: DeadlineExceeded or any net.Error whose Timeout() flag is set.
55 if errors.Is(err, context.DeadlineExceeded) {
56 return 504, "Gateway Timeout", UpstreamTimeoutMarker
57 }
58 var netErr net.Error
59 if errors.As(err, &netErr) && netErr.Timeout() {
60 return 504, "Gateway Timeout", UpstreamTimeoutMarker
61 }
62
63 // Mid-stream / early EOF: upstream closed the socket before sending a
64 // response (or mid-body). This is "bad gateway" territory rather than a
65 // timeout — but it is still something the recorder must persist rather
66 // than drop, otherwise replay cannot reproduce the observed error.
67 if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
68 return 502, "Bad Gateway", "keploy-recorded-upstream-eof: true"
69 }
70
71 // Connection-refused / reset / host-unreachable fall into a generic 502
72 // with a more specific marker so post-hoc analysis can pivot by error
73 // class.
74 msg := strings.ToLower(err.Error())
75 if strings.Contains(msg, "connection refused") ||
76 strings.Contains(msg, "connection reset") ||
77 strings.Contains(msg, "no route to host") ||
78 strings.Contains(msg, "broken pipe") {
79 return 502, "Bad Gateway", "keploy-recorded-upstream-unreachable: true"
80 }
81
82 // Everything else still gets persisted — default to 502 so replay sees a
83 // deterministic error instead of silently dropping.
84 return 502, "Bad Gateway", "keploy-recorded-upstream-error: true"
85}
86
87// upstreamErrorClass returns a short human label for an upstream error —
88// "timeout", "eof", "unreachable", or "other" — suitable for structured

Callers 2

Calls 2

TimeoutMethod · 0.65
ErrorMethod · 0.45

Tested by 1