A community based topic aggregation platform built on atproto
1package aggregator 2 3import ( 4 "encoding/json" 5 "log" 6 "net/http" 7 8 "Coves/internal/core/aggregators" 9) 10 11// ErrorResponse represents an XRPC error response 12type ErrorResponse struct { 13 Error string `json:"error"` 14 Message string `json:"message"` 15} 16 17// writeError writes a JSON error response 18func writeError(w http.ResponseWriter, statusCode int, errorType, message string) { 19 w.Header().Set("Content-Type", "application/json") 20 w.WriteHeader(statusCode) 21 if err := json.NewEncoder(w).Encode(ErrorResponse{ 22 Error: errorType, 23 Message: message, 24 }); err != nil { 25 log.Printf("ERROR: Failed to encode error response: %v", err) 26 } 27} 28 29// handleServiceError maps service errors to HTTP responses 30func handleServiceError(w http.ResponseWriter, err error) { 31 if err == nil { 32 return 33 } 34 35 // Map domain errors to HTTP status codes 36 switch { 37 case aggregators.IsNotFound(err): 38 writeError(w, http.StatusNotFound, "NotFound", err.Error()) 39 case aggregators.IsValidationError(err): 40 writeError(w, http.StatusBadRequest, "InvalidRequest", err.Error()) 41 case aggregators.IsUnauthorized(err): 42 writeError(w, http.StatusForbidden, "Forbidden", err.Error()) 43 case aggregators.IsConflict(err): 44 writeError(w, http.StatusConflict, "Conflict", err.Error()) 45 case aggregators.IsRateLimited(err): 46 writeError(w, http.StatusTooManyRequests, "RateLimitExceeded", err.Error()) 47 case aggregators.IsNotImplemented(err): 48 writeError(w, http.StatusNotImplemented, "NotImplemented", "This feature is not yet available (Phase 2)") 49 default: 50 // Internal errors - don't leak details 51 log.Printf("ERROR: Aggregator service error: %v", err) 52 writeError(w, http.StatusInternalServerError, "InternalServerError", 53 "An internal error occurred") 54 } 55}