Merge PR #1430
This commit is contained in:
commit
8aeb9c8735
2 changed files with 50 additions and 0 deletions
|
|
@ -50,6 +50,21 @@ var (
|
||||||
substr("context deadline exceeded"),
|
substr("context deadline exceeded"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transport layer error patterns that should trigger fallback.
|
||||||
|
transportPatterns = []errorPattern{
|
||||||
|
substr("connection reset by peer"),
|
||||||
|
substr("connection refused"),
|
||||||
|
substr("no route to host"),
|
||||||
|
substr("unexpected eof"),
|
||||||
|
substr("broken pipe"),
|
||||||
|
substr("connection closed"),
|
||||||
|
substr("connection reset"),
|
||||||
|
substr("eof"),
|
||||||
|
substr("network is unreachable"),
|
||||||
|
substr("temporary failure in name resolution"),
|
||||||
|
substr("dial tcp"),
|
||||||
|
}
|
||||||
|
|
||||||
billingPatterns = []errorPattern{
|
billingPatterns = []errorPattern{
|
||||||
rxp(`\b402\b`),
|
rxp(`\b402\b`),
|
||||||
substr("payment required"),
|
substr("payment required"),
|
||||||
|
|
@ -195,6 +210,9 @@ func classifyByMessage(msg string) FailoverReason {
|
||||||
if matchesAny(msg, timeoutPatterns) {
|
if matchesAny(msg, timeoutPatterns) {
|
||||||
return FailoverTimeout
|
return FailoverTimeout
|
||||||
}
|
}
|
||||||
|
if matchesAny(msg, transportPatterns) {
|
||||||
|
return FailoverTimeout // Transport errors treated as timeout (retriable)
|
||||||
|
}
|
||||||
if matchesAny(msg, authPatterns) {
|
if matchesAny(msg, authPatterns) {
|
||||||
return FailoverAuth
|
return FailoverAuth
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,3 +336,35 @@ func TestIsImageSizeError(t *testing.T) {
|
||||||
t.Error("should not match normal error")
|
t.Error("should not match normal error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClassifyError_TransportPatterns(t *testing.T) {
|
||||||
|
patterns := []string{
|
||||||
|
"connection reset by peer",
|
||||||
|
"connection refused",
|
||||||
|
"no route to host",
|
||||||
|
"unexpected EOF",
|
||||||
|
"broken pipe",
|
||||||
|
"connection closed",
|
||||||
|
"connection reset",
|
||||||
|
"EOF",
|
||||||
|
"network is unreachable",
|
||||||
|
"temporary failure in name resolution",
|
||||||
|
"dial tcp: lookup api.openrouter.ai: no such host",
|
||||||
|
"read tcp 10.0.0.1:12345->10.0.0.2:443: connection reset by peer",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, msg := range patterns {
|
||||||
|
err := errors.New(msg)
|
||||||
|
result := ClassifyError(err, "openrouter", "claude-3-opus")
|
||||||
|
if result == nil {
|
||||||
|
t.Errorf("pattern %q: expected non-nil", msg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if result.Reason != FailoverTimeout {
|
||||||
|
t.Errorf("pattern %q: reason = %q, want timeout", msg, result.Reason)
|
||||||
|
}
|
||||||
|
if !result.IsRetriable() {
|
||||||
|
t.Errorf("pattern %q: should be retriable", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue