| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- package service
- import "strings"
- type ChannelMonitorV2ErrorInput struct {
- ErrorType string
- ErrorOwner string
- ErrorSource string
- StatusCode int
- UpstreamStatusCode int
- Message string
- }
- // ClassifyChannelMonitorV2Error is deliberately ordered. Once rows are stored
- // with a taxonomy version, changing this order requires a new version.
- func ClassifyChannelMonitorV2Error(input ChannelMonitorV2ErrorInput) string {
- errorType := strings.ToLower(strings.TrimSpace(input.ErrorType))
- owner := strings.ToLower(strings.TrimSpace(input.ErrorOwner))
- text := strings.ToLower(strings.Join([]string{input.ErrorType, input.ErrorSource, input.Message}, " "))
- if errorType == "cyber_policy" || channelMonitorV2ContainsAny(text, "content policy", "content_policy", "safety policy", "moderation", "blocked keyword") {
- return "content_policy"
- }
- if input.StatusCode == 401 || input.UpstreamStatusCode == 401 || channelMonitorV2ContainsAny(text, "unauthorized", "invalid api key", "invalid_api_key", "authentication", "api_key_disabled") {
- return "authentication"
- }
- if channelMonitorV2ContainsAny(text, "context window", "context length", "maximum prompt length", "too many tokens", "max_tokens") {
- return "context_limit"
- }
- if channelMonitorV2ContainsAny(text, "failed to deserialize", "missing required parameter", "invalid request", "invalid_request", "tool_choice") {
- return "invalid_request"
- }
- if channelMonitorV2ContainsAny(text, "does not support the requested model", "not supported by any configured account", "model not supported", "unsupported model") {
- return "model_unsupported"
- }
- if channelMonitorV2ContainsAny(text, "group not allowed", "group_not_allowed", "group access") {
- return "group_access"
- }
- if channelMonitorV2ContainsAny(text, "run out of credits", "insufficient balance", "insufficient quota", "subscription", "quota exceeded", "billing hard limit") {
- return "quota_or_balance"
- }
- if channelMonitorV2ContainsAny(text, "no available accounts", "no healthy account", "no healthy upstream account", "failover budget exhausted", "account pool") {
- return "account_pool_unavailable"
- }
- if input.StatusCode == 429 || input.UpstreamStatusCode == 429 || channelMonitorV2ContainsAny(text, "rate limit", "rate_limit", "high demand", "overloaded", "concurrency limit", "capacity") {
- return "rate_or_capacity"
- }
- if input.StatusCode == 408 || input.StatusCode == 504 || channelMonitorV2ContainsAny(text, "timeout", "deadline exceeded", "error code: 524", "gateway time-out", "gateway timeout") {
- return "timeout"
- }
- if channelMonitorV2ContainsAny(text, "transport", "stream_read_error", "connection reset", "connection refused", "tls", "http2", "missing terminal event", "unexpected eof") {
- return "transport_or_stream"
- }
- if input.StatusCode == 403 || input.UpstreamStatusCode == 403 {
- return "upstream_forbidden"
- }
- if input.StatusCode == 404 || input.UpstreamStatusCode == 404 {
- return "not_found"
- }
- if input.StatusCode == 499 || channelMonitorV2ContainsAny(text, "client cancelled", "client canceled", "context canceled") {
- return "client_cancelled"
- }
- if input.UpstreamStatusCode >= 500 || (owner == "provider" && input.StatusCode >= 500) {
- return "upstream_5xx"
- }
- if input.StatusCode >= 500 || errorType == "internal" || owner == "system" {
- return "internal"
- }
- return "other"
- }
- func channelMonitorV2ContainsAny(value string, needles ...string) bool {
- for _, needle := range needles {
- if strings.Contains(value, needle) {
- return true
- }
- }
- return false
- }
|