A community based topic aggregation platform built on atproto
1package userblock
2
3import (
4 "Coves/internal/atproto/pds"
5 "Coves/internal/core/userblocks"
6 "encoding/json"
7 "errors"
8 "log/slog"
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, errCode, message string) {
20 w.Header().Set("Content-Type", "application/json")
21 w.WriteHeader(status)
22 if err := json.NewEncoder(w).Encode(XRPCError{
23 Error: errCode,
24 Message: message,
25 }); err != nil {
26 slog.Error("Failed to encode error response", "error", err)
27 }
28}
29
30// handleServiceError converts user block service errors to appropriate HTTP responses
31func handleServiceError(w http.ResponseWriter, err error) {
32 switch {
33 case errors.Is(err, userblocks.ErrBlockNotFound):
34 writeError(w, http.StatusNotFound, "NotFound", err.Error())
35 case errors.Is(err, userblocks.ErrBlockAlreadyExists):
36 writeError(w, http.StatusConflict, "AlreadyExists", err.Error())
37 case errors.Is(err, userblocks.ErrCannotBlockSelf):
38 writeError(w, http.StatusBadRequest, "InvalidRequest", "cannot block yourself")
39 // PDS-specific errors
40 case errors.Is(err, pds.ErrUnauthorized), errors.Is(err, pds.ErrForbidden):
41 writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required or session expired")
42 case errors.Is(err, pds.ErrBadRequest):
43 writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request to PDS")
44 case errors.Is(err, pds.ErrNotFound):
45 writeError(w, http.StatusNotFound, "NotFound", "Record not found on PDS")
46 case errors.Is(err, pds.ErrConflict):
47 writeError(w, http.StatusConflict, "Conflict", "Record was modified by another operation")
48 case errors.Is(err, pds.ErrRateLimited):
49 writeError(w, http.StatusTooManyRequests, "RateLimitExceeded", "Too many requests, please try again later")
50 case errors.Is(err, pds.ErrPayloadTooLarge):
51 writeError(w, http.StatusRequestEntityTooLarge, "PayloadTooLarge", "Request payload exceeds size limit")
52 default:
53 slog.Error("XRPC user block handler error", "error", err)
54 writeError(w, http.StatusInternalServerError, "InternalServerError", "An internal error occurred")
55 }
56}