Files
AIRouter/internal/handler/errors.go
T
freedakgmail 93a469061d
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled
CI / security-scan (push) Has been cancelled
初始提交:边缘AI算力机统一AI通讯层
2026-08-03 07:44:05 +08:00

104 lines
3.0 KiB
Go

package handler
import (
"encoding/json"
"net/http"
"github.com/edgeai/gateway/pkg/api"
"github.com/google/uuid"
)
// ErrorCode constants.
const (
ErrAuthFailed = "AUTH_FAILED"
ErrPermissionDenied = "PERMISSION_DENIED"
ErrPolicyBlocked = "POLICY_BLOCKED"
ErrRateLimited = "RATE_LIMITED"
ErrQuotaExceeded = "QUOTA_EXCEEDED"
ErrQueueFull = "QUEUE_FULL"
ErrInvalidRequest = "INVALID_REQUEST"
ErrContextTooLarge = "CONTEXT_TOO_LARGE"
ErrQueueTimeout = "QUEUE_TIMEOUT"
ErrFirstTokenTimeout = "FIRST_TOKEN_TIMEOUT"
ErrInferenceTimeout = "INFERENCE_TIMEOUT"
ErrRequestCancelled = "REQUEST_CANCELLED"
ErrModelUnavailable = "MODEL_UNAVAILABLE"
ErrResourceExhausted = "RESOURCE_EXHAUSTED"
ErrInternalError = "INTERNAL_ERROR"
)
// httpStatusForCode maps error codes to HTTP status codes.
var httpStatusForCode = map[string]int{
ErrAuthFailed: http.StatusUnauthorized,
ErrPermissionDenied: http.StatusForbidden,
ErrPolicyBlocked: http.StatusForbidden,
ErrRateLimited: http.StatusTooManyRequests,
ErrQuotaExceeded: http.StatusTooManyRequests,
ErrQueueFull: http.StatusTooManyRequests,
ErrInvalidRequest: http.StatusBadRequest,
ErrContextTooLarge: http.StatusBadRequest,
ErrQueueTimeout: http.StatusRequestTimeout,
ErrFirstTokenTimeout: http.StatusRequestTimeout,
ErrInferenceTimeout: http.StatusRequestTimeout,
ErrRequestCancelled: http.StatusConflict,
ErrModelUnavailable: http.StatusServiceUnavailable,
ErrResourceExhausted: http.StatusServiceUnavailable,
ErrInternalError: http.StatusInternalServerError,
}
// GatewayError represents a structured error with code, message, and request ID.
type GatewayError struct {
Code string
Message string
RequestID string
}
func (e *GatewayError) Error() string {
return e.Message
}
// NewGatewayError creates a GatewayError with a generated request ID.
func NewGatewayError(code, message string) *GatewayError {
return &GatewayError{
Code: code,
Message: message,
RequestID: uuid.New().String(),
}
}
// NewGatewayErrorWithID creates a GatewayError with an existing request ID.
func NewGatewayErrorWithID(code, message, requestID string) *GatewayError {
return &GatewayError{
Code: code,
Message: message,
RequestID: requestID,
}
}
// WriteError writes a structured error response.
func WriteError(w http.ResponseWriter, err *GatewayError) {
status, ok := httpStatusForCode[err.Code]
if !ok {
status = http.StatusInternalServerError
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
resp := api.ErrorResponse{
Error: api.ErrorBody{
Code: err.Code,
Message: err.Message,
RequestID: err.RequestID,
},
}
json.NewEncoder(w).Encode(resp)
}
// WriteJSON writes a JSON response with the given status code.
func WriteJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}