From 470f178ac079b29e1523174ff6257f942bc0705e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 23:00:26 +0000 Subject: [PATCH] Log errors from Redis cache operations and audit log insertions Previously, cache errors in the evaluate handler were silently discarded (flag, _ := h.cache.GetFlag), which hid connection errors, serialization errors, and Redis outages. Similarly, audit log insertion errors in the flag handler were unchecked, meaning failures from Postgres pressure or full tables would go unnoticed. Now all cache and audit log errors are logged via log.Printf so operators can detect when Redis is unhealthy or audit data is being lost. https://claude.ai/code/session_01JDqcjWMkkrAyY2CxALpmm3 --- api/internal/handler/evaluate.go | 10 ++++++++-- api/internal/handler/flags.go | 29 ++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/api/internal/handler/evaluate.go b/api/internal/handler/evaluate.go index e903032..ea65378 100644 --- a/api/internal/handler/evaluate.go +++ b/api/internal/handler/evaluate.go @@ -1,6 +1,7 @@ package handler import ( + "log" "net/http" "github.com/davigiroux/flagkit/api/internal/cache" @@ -23,7 +24,10 @@ func (h *EvalHandler) Evaluate(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("user_id") // Try cache first - flag, _ := h.cache.GetFlag(r.Context(), key) + flag, err := h.cache.GetFlag(r.Context(), key) + if err != nil { + log.Printf("cache error for flag %q: %v", key, err) + } if flag == nil { var err error flag, err = h.queries.GetFlagByKey(r.Context(), key) @@ -31,7 +35,9 @@ func (h *EvalHandler) Evaluate(w http.ResponseWriter, r *http.Request) { writeError(w, http.StatusNotFound, "flag not found") return } - h.cache.SetFlag(r.Context(), flag) + if err := h.cache.SetFlag(r.Context(), flag); err != nil { + log.Printf("cache set error for flag %q: %v", key, err) + } } result := evaluate.Evaluate(flag, userID) diff --git a/api/internal/handler/flags.go b/api/internal/handler/flags.go index 3fa2fc7..ec66948 100644 --- a/api/internal/handler/flags.go +++ b/api/internal/handler/flags.go @@ -2,6 +2,7 @@ package handler import ( "encoding/json" + "log" "net/http" "github.com/davigiroux/flagkit/api/internal/audit" @@ -60,7 +61,9 @@ func (h *FlagHandler) Create(w http.ResponseWriter, r *http.Request) { return } - h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditCreated, audit.FlagSnapshot(flag), middleware.GetActor(r.Context())) + if err := h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditCreated, audit.FlagSnapshot(flag), middleware.GetActor(r.Context())); err != nil { + log.Printf("audit log error (create flag %q): %v", flag.Key, err) + } writeJSON(w, http.StatusCreated, flag) } @@ -86,9 +89,13 @@ func (h *FlagHandler) Update(w http.ResponseWriter, r *http.Request) { } diff := audit.ComputeDiff(oldFlag, flag) - h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditUpdated, audit.MarshalDiff(diff), middleware.GetActor(r.Context())) + if err := h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditUpdated, audit.MarshalDiff(diff), middleware.GetActor(r.Context())); err != nil { + log.Printf("audit log error (update flag %q): %v", key, err) + } - h.cache.InvalidateFlag(r.Context(), key) + if err := h.cache.InvalidateFlag(r.Context(), key); err != nil { + log.Printf("cache invalidation error for flag %q: %v", key, err) + } writeJSON(w, http.StatusOK, flag) } @@ -106,9 +113,13 @@ func (h *FlagHandler) Delete(w http.ResponseWriter, r *http.Request) { return } - h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditDeleted, audit.FlagDeleteSnapshot(flag), middleware.GetActor(r.Context())) + if err := h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditDeleted, audit.FlagDeleteSnapshot(flag), middleware.GetActor(r.Context())); err != nil { + log.Printf("audit log error (delete flag %q): %v", key, err) + } - h.cache.InvalidateFlag(r.Context(), key) + if err := h.cache.InvalidateFlag(r.Context(), key); err != nil { + log.Printf("cache invalidation error for flag %q: %v", key, err) + } w.WriteHeader(http.StatusNoContent) } @@ -128,9 +139,13 @@ func (h *FlagHandler) Toggle(w http.ResponseWriter, r *http.Request) { } diff := audit.ComputeDiff(oldFlag, flag) - h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditToggled, audit.MarshalDiff(diff), middleware.GetActor(r.Context())) + if err := h.queries.InsertAuditLog(r.Context(), flag.ID, model.AuditToggled, audit.MarshalDiff(diff), middleware.GetActor(r.Context())); err != nil { + log.Printf("audit log error (toggle flag %q): %v", key, err) + } - h.cache.InvalidateFlag(r.Context(), key) + if err := h.cache.InvalidateFlag(r.Context(), key); err != nil { + log.Printf("cache invalidation error for flag %q: %v", key, err) + } writeJSON(w, http.StatusOK, flag) }