package errors import ( "encoding/json" "fmt" "net/http" "os" chimiddleware "github.com/go-chi/chi/v5/middleware" "github.com/google/uuid" ) // ErrorCode represents standardized error codes type ErrorCode string const ( CodeUnauthenticated ErrorCode = "UNAUTHENTICATED" CodePermissionDenied ErrorCode = "PERMISSION_DENIED" CodeNotFound ErrorCode = "NOT_FOUND" CodeConflict ErrorCode = "CONFLICT" CodeInvalidArgument ErrorCode = "INVALID_ARGUMENT" CodeInternal ErrorCode = "INTERNAL" ) // ErrorResponse represents the JSON error response structure type ErrorResponse struct { Code ErrorCode `json:"code"` Message string `json:"message"` } // WriteError writes a standardized JSON error response func WriteError(w http.ResponseWriter, code ErrorCode, message string, status int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) json.NewEncoder(w).Encode(ErrorResponse{ Code: code, Message: message, }) } // GetRequestID extracts the request ID from the request context func GetRequestID(r *http.Request) string { if reqID := chimiddleware.GetReqID(r.Context()); reqID != "" { return reqID } return "unknown" } // GetUserID extracts user ID from context if available func GetUserID(r *http.Request) string { // Use type contextKey matching middleware package type contextKey string if userID, ok := r.Context().Value(contextKey("user")).(string); ok && userID != "" { return userID } return "" } // GetOrgID extracts org ID from context if available func GetOrgID(r *http.Request) string { if orgID := r.Context().Value("org"); orgID != nil { if oid, ok := orgID.(uuid.UUID); ok { return oid.String() } } return "" } // LogError logs an error with context func LogError(r *http.Request, err error, message string) { fmt.Fprintf(os.Stderr, "[ERROR] req_id=%s user_id=%s org_id=%s %s: %v\n", GetRequestID(r), GetUserID(r), GetOrgID(r), message, err) }