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}