Skip to content

Commit 2ba8388

Browse files
authored
feat(error): Add typed error for NOSCRIPT replies from Redis (#3738)
1 parent 60b46d9 commit 2ba8388

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

commands_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package redis_test
22

33
import (
44
"context"
5+
"crypto/rand"
6+
"crypto/sha1"
57
"encoding/json"
68
"fmt"
79
"reflect"
@@ -8648,6 +8650,21 @@ var _ = Describe("Commands", func() {
86488650
Expect(err).NotTo(HaveOccurred())
86498651
Expect(vals).To(BeEmpty())
86508652
})
8653+
8654+
It("propagates NOSCRIPT errors on EVALSHA of an unknown digest", func() {
8655+
digest := make([]byte, 32)
8656+
_, err := rand.Read(digest)
8657+
Expect(err).NotTo(HaveOccurred())
8658+
8659+
_, err = client.EvalSha(
8660+
ctx,
8661+
fmt.Sprintf("%x", sha1.Sum(digest)),
8662+
[]string{},
8663+
nil,
8664+
).Result()
8665+
Expect(err).To(HaveOccurred())
8666+
Expect(err).To(MatchError(redis.ErrNoScript))
8667+
})
86518668
})
86528669

86538670
Describe("EvalRO", func() {
@@ -8682,6 +8699,21 @@ var _ = Describe("Commands", func() {
86828699
Expect(err).NotTo(HaveOccurred())
86838700
Expect(vals).To(BeEmpty())
86848701
})
8702+
8703+
It("propagates NOSCRIPT errors on EVALSHA_RO of an unknown digest", func() {
8704+
digest := make([]byte, 32)
8705+
_, err := rand.Read(digest)
8706+
Expect(err).NotTo(HaveOccurred())
8707+
8708+
_, err = client.EvalShaRO(
8709+
ctx,
8710+
fmt.Sprintf("%x", sha1.Sum(digest)),
8711+
[]string{},
8712+
nil,
8713+
).Result()
8714+
Expect(err).To(HaveOccurred())
8715+
Expect(err).To(MatchError(redis.ErrNoScript))
8716+
})
86858717
})
86868718

86878719
Describe("Functions", func() {

error.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ var ErrPoolTimeout = pool.ErrPoolTimeout
2828
// is used on a ClusterClient with keys in different slots.
2929
var ErrCrossSlot = proto.RedisError("CROSSSLOT Keys in request don't hash to the same slot")
3030

31+
// ErrNoScript is returned when EVALSHA is requested for a script digest that
32+
// is not available in the script cache. Note that this error text is reproduced
33+
// literally from that used by Redis.
34+
var ErrNoScript = proto.RedisError("NOSCRIPT No matching script. Please use EVAL.")
35+
3136
// HasErrorPrefix checks if the err is a Redis error and the message contains a prefix.
3237
func HasErrorPrefix(err error, prefix string) bool {
3338
var rErr Error

script.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/sha1"
66
"encoding/hex"
7+
"errors"
78
"io"
89
)
910

@@ -67,7 +68,7 @@ func (s *Script) EvalShaRO(ctx context.Context, c Scripter, keys []string, args
6768
// it is retried using EVAL.
6869
func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
6970
r := s.EvalSha(ctx, c, keys, args...)
70-
if HasErrorPrefix(r.Err(), "NOSCRIPT") {
71+
if errors.Is(r.Err(), ErrNoScript) {
7172
return s.Eval(ctx, c, keys, args...)
7273
}
7374
return r
@@ -77,7 +78,7 @@ func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...int
7778
// it is retried using EVAL_RO.
7879
func (s *Script) RunRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
7980
r := s.EvalShaRO(ctx, c, keys, args...)
80-
if HasErrorPrefix(r.Err(), "NOSCRIPT") {
81+
if errors.Is(r.Err(), ErrNoScript) {
8182
return s.EvalRO(ctx, c, keys, args...)
8283
}
8384
return r

scripting_commands.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ func (c cmdable) eval(ctx context.Context, name, payload string, keys []string,
6060
cmd.SetFirstKeyPos(3)
6161
}
6262
_ = c(ctx, cmd)
63+
if err := cmd.Err(); err != nil {
64+
if HasErrorPrefix(err, "NOSCRIPT") {
65+
cmd.SetErr(ErrNoScript)
66+
}
67+
}
6368
return cmd
6469
}
6570

0 commit comments

Comments
 (0)