mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-09-03 06:35:00 +08:00
fix(cliproxy): centralize client error status mapping and apply context cancellation/deadline HTTP codes
Closes: #4601
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
package clienterror
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
@@ -10,6 +11,10 @@ import (
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// StatusClientClosedRequest is the nginx-style status used when the client
|
||||
// aborts the request before the proxy finishes (context.Canceled).
|
||||
const StatusClientClosedRequest = 499
|
||||
|
||||
var requestFaultCodes = map[string]struct{}{
|
||||
"cyber_policy": {},
|
||||
"context_length_exceeded": {},
|
||||
@@ -29,6 +34,40 @@ var requestFaultTypes = map[string]struct{}{
|
||||
"invalid_prompt": {},
|
||||
}
|
||||
|
||||
// HTTPStatusFromError extracts an HTTP status from err.
|
||||
// Explicit StatusCode() values win. Otherwise context.Canceled maps to 499
|
||||
// and context.DeadlineExceeded maps to 504. Returns 0 when unknown.
|
||||
func HTTPStatusFromError(err error) int {
|
||||
if err == nil {
|
||||
return 0
|
||||
}
|
||||
type statusCoder interface {
|
||||
StatusCode() int
|
||||
}
|
||||
var sc statusCoder
|
||||
if errors.As(err, &sc) && sc != nil {
|
||||
if code := sc.StatusCode(); code > 0 {
|
||||
return code
|
||||
}
|
||||
}
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return StatusClientClosedRequest
|
||||
}
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return http.StatusGatewayTimeout
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// HTTPStatusFromErrorOr is like HTTPStatusFromError but returns fallback when
|
||||
// the error does not carry a known status.
|
||||
func HTTPStatusFromErrorOr(err error, fallback int) int {
|
||||
if code := HTTPStatusFromError(err); code > 0 {
|
||||
return code
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// IsRequestFault reports whether an upstream failure is caused by the request
|
||||
// and therefore must not rotate or penalize credentials.
|
||||
func IsRequestFault(status int, err error) bool {
|
||||
|
||||
Reference in New Issue
Block a user