fix: replace silent json.Encode with error-logging pattern across all handlers

This commit is contained in:
2026-07-11 17:50:07 +01:00
parent 0bef0f7973
commit 5d9fa1178b
24 changed files with 629 additions and 433 deletions
+70 -44
View File
@@ -332,7 +332,9 @@ func GetGiftCards(w http.ResponseWriter, r *http.Request) {
}
resp.TotalPages = totalPages
_ = json.NewEncoder(w).Encode(resp)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
func CreateGiftCard(w http.ResponseWriter, r *http.Request) {
@@ -361,10 +363,10 @@ func CreateGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var gc GiftCard
var lastUsedAt sql.NullTime
@@ -426,7 +428,9 @@ func CreateGiftCard(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusCreated)
_ = json.NewEncoder(w).Encode(gc)
if err := json.NewEncoder(w).Encode(gc); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
func TopUpGiftCard(w http.ResponseWriter, r *http.Request) {
@@ -468,10 +472,10 @@ func TopUpGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var redeemedBy sql.NullString
var isInventory bool
@@ -542,7 +546,9 @@ func TopUpGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
_ = json.NewEncoder(w).Encode(gc)
if err := json.NewEncoder(w).Encode(gc); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
func TransferGiftCard(w http.ResponseWriter, r *http.Request) {
@@ -582,10 +588,10 @@ func TransferGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var fromRedeemedBy, toRedeemedBy sql.NullString
var fromRemaining, toRemaining float64
@@ -654,7 +660,9 @@ func TransferGiftCard(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(map[string]string{"status": "success"})
if err := json.NewEncoder(w).Encode(map[string]string{"status": "success"}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
// --- User Handlers ---
@@ -686,10 +694,10 @@ func RedeemGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var amountRemaining float64
var redeemedBy sql.NullString
@@ -762,10 +770,12 @@ func RedeemGiftCard(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(map[string]any{
if err := json.NewEncoder(w).Encode(map[string]any{
"status": "success",
"amount_redeemed": amountRemaining,
})
}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
func GetGiftCardBalance(w http.ResponseWriter, r *http.Request) {
@@ -780,7 +790,9 @@ func GetGiftCardBalance(w http.ResponseWriter, r *http.Request) {
err := db.Conn.QueryRow(ctx, "SELECT balance FROM user_giftcard_balances WHERE user_id = $1", userID).Scan(&balance)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
_ = json.NewEncoder(w).Encode(map[string]float64{"balance": 0.00})
if err := json.NewEncoder(w).Encode(map[string]float64{"balance": 0.00}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
return
}
log.Printf("Failed to query user balance: %v", err)
@@ -788,7 +800,9 @@ func GetGiftCardBalance(w http.ResponseWriter, r *http.Request) {
return
}
_ = json.NewEncoder(w).Encode(map[string]float64{"balance": balance})
if err := json.NewEncoder(w).Encode(map[string]float64{"balance": balance}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
// GetUserGiftCardBalanceAdmin Handler returns any user's balance for the admin.
@@ -806,7 +820,9 @@ func GetUserGiftCardBalanceAdmin(w http.ResponseWriter, r *http.Request) {
err := db.Conn.QueryRow(ctx, "SELECT balance FROM user_giftcard_balances WHERE user_id = $1", userID).Scan(&balance)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
_ = json.NewEncoder(w).Encode(map[string]float64{"balance": 0.00})
if err := json.NewEncoder(w).Encode(map[string]float64{"balance": 0.00}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
return
}
log.Printf("Failed to query user balance: %v", err)
@@ -821,10 +837,10 @@ func GetUserGiftCardBalanceAdmin(w http.ResponseWriter, r *http.Request) {
log.Printf("Failed to begin transaction: %v", err)
} else {
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if _, err := tx.Exec(ctx, `
INSERT INTO admin_audit_log (admin_id, action_type, target_user_id, details)
@@ -838,7 +854,9 @@ func GetUserGiftCardBalanceAdmin(w http.ResponseWriter, r *http.Request) {
}
}
_ = json.NewEncoder(w).Encode(map[string]float64{"balance": balance})
if err := json.NewEncoder(w).Encode(map[string]float64{"balance": balance}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
func BuyGiftCard(w http.ResponseWriter, r *http.Request) {
@@ -880,7 +898,9 @@ func BuyGiftCard(w http.ResponseWriter, r *http.Request) {
log.Printf("Failed to check idempotency: %v", err)
}
if existing != nil {
_ = json.NewEncoder(w).Encode(existing)
if err := json.NewEncoder(w).Encode(existing); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
return
}
}
@@ -933,10 +953,10 @@ func BuyGiftCard(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var buyPaymentID string
fees := paymentService.CalculateFees(req.Amount, "online")
@@ -1107,11 +1127,13 @@ func BuyGiftCard(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusCreated)
_ = json.NewEncoder(w).Encode(map[string]any{
if err := json.NewEncoder(w).Encode(map[string]any{
"status": "success",
"code": cardID,
"amount": amountPounds,
})
}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
// --- Helpers ---
@@ -1179,10 +1201,12 @@ func GetExpiredBalances(w http.ResponseWriter, r *http.Request) {
balances = []ExpiredBalance{}
}
_ = json.NewEncoder(w).Encode(map[string]any{
if err := json.NewEncoder(w).Encode(map[string]any{
"expired_balances": balances,
"total": len(balances),
})
}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}
type ClaimExpiredBalanceRequest struct {
@@ -1216,10 +1240,10 @@ func ClaimExpiredBalance(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
if err := tx.Rollback(ctx); err != nil && err.Error() != "tx is closed" {
slog.Error("failed to rollback transaction", "err", err)
}
}()
var existingClaimedAt sql.NullTime
err = tx.QueryRow(ctx, `
@@ -1258,5 +1282,7 @@ func ClaimExpiredBalance(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(map[string]string{"status": "claimed"})
if err := json.NewEncoder(w).Encode(map[string]string{"status": "claimed"}); err != nil {
log.Printf("Failed to encode JSON response: %v", err)
}
}