A community based topic aggregation platform built on atproto
1package vote
2
3import (
4 "Coves/internal/core/votes"
5 "encoding/json"
6 "errors"
7 "log"
8 "net/http"
9)
10
11// XRPCError represents an XRPC error response
12type XRPCError struct {
13 Error string `json:"error"`
14 Message string `json:"message"`
15}
16
17// writeError writes an XRPC error response
18func writeError(w http.ResponseWriter, status int, error, message string) {
19 w.Header().Set("Content-Type", "application/json")
20 w.WriteHeader(status)
21 if err := json.NewEncoder(w).Encode(XRPCError{
22 Error: error,
23 Message: message,
24 }); err != nil {
25 log.Printf("Failed to encode error response: %v", err)
26 }
27}
28
29// handleServiceError converts service errors to appropriate HTTP responses
30// Error names MUST match lexicon definitions exactly (UpperCamelCase)
31// Uses errors.Is() to handle wrapped errors correctly
32func handleServiceError(w http.ResponseWriter, err error) {
33 switch {
34 case errors.Is(err, votes.ErrVoteNotFound):
35 // Matches: social.coves.feed.vote.delete#VoteNotFound
36 writeError(w, http.StatusNotFound, "VoteNotFound", "No vote found for this subject")
37 case errors.Is(err, votes.ErrInvalidDirection):
38 writeError(w, http.StatusBadRequest, "InvalidRequest", "Vote direction must be 'up' or 'down'")
39 case errors.Is(err, votes.ErrInvalidSubject):
40 // Matches: social.coves.feed.vote.create#InvalidSubject
41 writeError(w, http.StatusBadRequest, "InvalidSubject", "The subject reference is invalid or malformed")
42 case errors.Is(err, votes.ErrVoteAlreadyExists):
43 writeError(w, http.StatusConflict, "AlreadyExists", "Vote already exists")
44 case errors.Is(err, votes.ErrNotAuthorized):
45 // Matches: social.coves.feed.vote.create#NotAuthorized, social.coves.feed.vote.delete#NotAuthorized
46 writeError(w, http.StatusForbidden, "NotAuthorized", "User is not authorized to vote on this content")
47 case errors.Is(err, votes.ErrBanned):
48 writeError(w, http.StatusForbidden, "NotAuthorized", "User is not authorized to vote on this content")
49 default:
50 // Internal server error - log the actual error for debugging
51 log.Printf("XRPC handler error: %v", err)
52 writeError(w, http.StatusInternalServerError, "InternalServerError", "An internal error occurred")
53 }
54}