mirror of
				https://github.com/redis/go-redis.git
				synced 2025-11-04 02:33:24 +03:00 
			
		
		
		
	fix(panic): Return error instead of panic from commands (#3568)
Instead of panic in few commands, we can return an error to avoid unexpected panics in application code.
This commit is contained in:
		@@ -141,7 +141,9 @@ func (c cmdable) BitPos(ctx context.Context, key string, bit int64, pos ...int64
 | 
			
		||||
		args[3] = pos[0]
 | 
			
		||||
		args[4] = pos[1]
 | 
			
		||||
	default:
 | 
			
		||||
		panic("too many arguments")
 | 
			
		||||
		cmd := NewIntCmd(ctx)
 | 
			
		||||
		cmd.SetErr(errors.New("too many arguments"))
 | 
			
		||||
		return cmd
 | 
			
		||||
	}
 | 
			
		||||
	cmd := NewIntCmd(ctx, args...)
 | 
			
		||||
	_ = c(ctx, cmd)
 | 
			
		||||
@@ -182,7 +184,9 @@ func (c cmdable) BitFieldRO(ctx context.Context, key string, values ...interface
 | 
			
		||||
	args[0] = "BITFIELD_RO"
 | 
			
		||||
	args[1] = key
 | 
			
		||||
	if len(values)%2 != 0 {
 | 
			
		||||
		panic("BitFieldRO: invalid number of arguments, must be even")
 | 
			
		||||
		c := NewIntSliceCmd(ctx)
 | 
			
		||||
		c.SetErr(errors.New("BitFieldRO: invalid number of arguments, must be even"))
 | 
			
		||||
		return c
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < len(values); i += 2 {
 | 
			
		||||
		args = append(args, "GET", values[i], values[i+1])
 | 
			
		||||
 
 | 
			
		||||
@@ -693,7 +693,9 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I
 | 
			
		||||
	args := []interface{}{"memory", "usage", key}
 | 
			
		||||
	if len(samples) > 0 {
 | 
			
		||||
		if len(samples) != 1 {
 | 
			
		||||
			panic("MemoryUsage expects single sample count")
 | 
			
		||||
			cmd := NewIntCmd(ctx)
 | 
			
		||||
			cmd.SetErr(errors.New("MemoryUsage expects single sample count"))
 | 
			
		||||
			return cmd
 | 
			
		||||
		}
 | 
			
		||||
		args = append(args, "SAMPLES", samples[0])
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -735,6 +735,9 @@ var _ = Describe("Commands", func() {
 | 
			
		||||
			n, err = client.MemoryUsage(ctx, "foo", 0).Result()
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			Expect(n).NotTo(BeZero())
 | 
			
		||||
 | 
			
		||||
			_, err = client.MemoryUsage(ctx, "foo", 0, 1).Result()
 | 
			
		||||
			Expect(err).Should(MatchError("MemoryUsage expects single sample count"))
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
@@ -1598,6 +1601,9 @@ var _ = Describe("Commands", func() {
 | 
			
		||||
			pos, err = client.BitPos(ctx, "mykey", 0, 0, 0).Result()
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			Expect(pos).To(Equal(int64(-1)))
 | 
			
		||||
 | 
			
		||||
			_, err = client.BitPos(ctx, "mykey", 0, 0, 0, 0, 0).Result()
 | 
			
		||||
			Expect(err).Should(MatchError("too many arguments"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should BitPosSpan", func() {
 | 
			
		||||
@@ -1635,6 +1641,9 @@ var _ = Describe("Commands", func() {
 | 
			
		||||
			nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4", 13).Result()
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			Expect(nn).To(Equal([]int64{0, 15, 15, 14}))
 | 
			
		||||
 | 
			
		||||
			_, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4").Result()
 | 
			
		||||
			Expect(err).Should(MatchError("BitFieldRO: invalid number of arguments, must be even"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should Decr", func() {
 | 
			
		||||
@@ -5254,6 +5263,9 @@ var _ = Describe("Commands", func() {
 | 
			
		||||
				Score:  1,
 | 
			
		||||
				Member: "one",
 | 
			
		||||
			}}))
 | 
			
		||||
 | 
			
		||||
			_, err = client.ZPopMax(ctx, "zset", 10, 11).Result()
 | 
			
		||||
			Expect(err).Should(MatchError("too many arguments"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should ZPopMin", func() {
 | 
			
		||||
@@ -5321,6 +5333,9 @@ var _ = Describe("Commands", func() {
 | 
			
		||||
				Score:  3,
 | 
			
		||||
				Member: "three",
 | 
			
		||||
			}}))
 | 
			
		||||
 | 
			
		||||
			_, err = client.ZPopMin(ctx, "zset", 10, 11).Result()
 | 
			
		||||
			Expect(err).Should(MatchError("too many arguments"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should ZRange", func() {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package redis
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@@ -313,7 +314,9 @@ func (c cmdable) ZPopMax(ctx context.Context, key string, count ...int64) *ZSlic
 | 
			
		||||
	case 1:
 | 
			
		||||
		args = append(args, count[0])
 | 
			
		||||
	default:
 | 
			
		||||
		panic("too many arguments")
 | 
			
		||||
		cmd := NewZSliceCmd(ctx)
 | 
			
		||||
		cmd.SetErr(errors.New("too many arguments"))
 | 
			
		||||
		return cmd
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd := NewZSliceCmd(ctx, args...)
 | 
			
		||||
@@ -333,7 +336,9 @@ func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSlic
 | 
			
		||||
	case 1:
 | 
			
		||||
		args = append(args, count[0])
 | 
			
		||||
	default:
 | 
			
		||||
		panic("too many arguments")
 | 
			
		||||
		cmd := NewZSliceCmd(ctx)
 | 
			
		||||
		cmd.SetErr(errors.New("too many arguments"))
 | 
			
		||||
		return cmd
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd := NewZSliceCmd(ctx, args...)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user