A community based topic aggregation platform built on atproto
at main 62 lines 2.4 kB view raw
1package community 2 3import ( 4 "Coves/internal/atproto/pds" 5 "Coves/internal/core/communities" 6 "encoding/json" 7 "errors" 8 "log" 9 "net/http" 10) 11 12// XRPCError represents an XRPC error response 13type XRPCError struct { 14 Error string `json:"error"` 15 Message string `json:"message"` 16} 17 18// writeError writes an XRPC error response 19func writeError(w http.ResponseWriter, status int, error, message string) { 20 w.Header().Set("Content-Type", "application/json") 21 w.WriteHeader(status) 22 if err := json.NewEncoder(w).Encode(XRPCError{ 23 Error: error, 24 Message: message, 25 }); err != nil { 26 log.Printf("Failed to encode error response: %v", err) 27 } 28} 29 30// handleServiceError converts service errors to appropriate HTTP responses 31func handleServiceError(w http.ResponseWriter, err error) { 32 switch { 33 case communities.IsNotFound(err): 34 writeError(w, http.StatusNotFound, "NotFound", err.Error()) 35 case communities.IsConflict(err): 36 if err == communities.ErrHandleTaken { 37 writeError(w, http.StatusConflict, "NameTaken", "Community handle is already taken") 38 } else { 39 writeError(w, http.StatusConflict, "AlreadyExists", err.Error()) 40 } 41 case communities.IsValidationError(err): 42 writeError(w, http.StatusBadRequest, "InvalidRequest", err.Error()) 43 case err == communities.ErrUnauthorized: 44 writeError(w, http.StatusForbidden, "Forbidden", "You do not have permission to perform this action") 45 case err == communities.ErrMemberBanned: 46 writeError(w, http.StatusForbidden, "Blocked", "You are blocked from this community") 47 // PDS-specific errors (from DPoP authentication or PDS API calls) 48 case errors.Is(err, pds.ErrBadRequest): 49 writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request to PDS") 50 case errors.Is(err, pds.ErrNotFound): 51 writeError(w, http.StatusNotFound, "NotFound", "Record not found on PDS") 52 case errors.Is(err, pds.ErrConflict): 53 writeError(w, http.StatusConflict, "Conflict", "Record was modified by another operation") 54 case errors.Is(err, pds.ErrUnauthorized), errors.Is(err, pds.ErrForbidden): 55 // PDS auth errors should prompt re-authentication 56 writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required or session expired") 57 default: 58 // Internal server error - log the actual error for debugging 59 log.Printf("XRPC handler error: %v", err) 60 writeError(w, http.StatusInternalServerError, "InternalServerError", "An internal error occurred") 61 } 62}