fix(cache): harden nil receiver handling
This commit is contained in:
parent
529e60f3ff
commit
41150c0548
2 changed files with 55 additions and 2 deletions
28
cache.go
28
cache.go
|
|
@ -29,8 +29,8 @@ type Cache struct {
|
|||
// Entry is the serialized cache record written to the backing Medium.
|
||||
type Entry struct {
|
||||
Data json.RawMessage `json:"data"`
|
||||
CachedAt time.Time `json:"cached_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
CachedAt time.Time `json:"cached_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
// New creates a cache and applies default Medium, base directory, and TTL values
|
||||
|
|
@ -73,6 +73,10 @@ func New(medium coreio.Medium, baseDir string, ttl time.Duration) (*Cache, error
|
|||
//
|
||||
// path, err := c.Path("github/acme/repos")
|
||||
func (c *Cache) Path(key string) (string, error) {
|
||||
if c == nil {
|
||||
return "", core.E("cache.Path", "cache is nil", nil)
|
||||
}
|
||||
|
||||
baseDir := absolutePath(c.baseDir)
|
||||
path := absolutePath(core.JoinPath(baseDir, key+".json"))
|
||||
pathPrefix := normalizePath(core.Concat(baseDir, pathSeparator()))
|
||||
|
|
@ -88,6 +92,10 @@ func (c *Cache) Path(key string) (string, error) {
|
|||
//
|
||||
// found, err := c.Get("github/acme/repos", &repos)
|
||||
func (c *Cache) Get(key string, dest any) (bool, error) {
|
||||
if c == nil {
|
||||
return false, core.E("cache.Get", "cache is nil", nil)
|
||||
}
|
||||
|
||||
path, err := c.Path(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
@ -122,6 +130,10 @@ func (c *Cache) Get(key string, dest any) (bool, error) {
|
|||
//
|
||||
// err := c.Set("github/acme/repos", repos)
|
||||
func (c *Cache) Set(key string, data any) error {
|
||||
if c == nil {
|
||||
return core.E("cache.Set", "cache is nil", nil)
|
||||
}
|
||||
|
||||
path, err := c.Path(key)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -157,6 +169,10 @@ func (c *Cache) Set(key string, data any) error {
|
|||
//
|
||||
// err := c.Delete("github/acme/repos")
|
||||
func (c *Cache) Delete(key string) error {
|
||||
if c == nil {
|
||||
return core.E("cache.Delete", "cache is nil", nil)
|
||||
}
|
||||
|
||||
path, err := c.Path(key)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -176,6 +192,10 @@ func (c *Cache) Delete(key string) error {
|
|||
//
|
||||
// err := c.Clear()
|
||||
func (c *Cache) Clear() error {
|
||||
if c == nil {
|
||||
return core.E("cache.Clear", "cache is nil", nil)
|
||||
}
|
||||
|
||||
if err := c.medium.DeleteAll(c.baseDir); err != nil {
|
||||
return core.E("cache.Clear", "failed to clear cache", err)
|
||||
}
|
||||
|
|
@ -186,6 +206,10 @@ func (c *Cache) Clear() error {
|
|||
//
|
||||
// age := c.Age("github/acme/repos")
|
||||
func (c *Cache) Age(key string) time.Duration {
|
||||
if c == nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
path, err := c.Path(key)
|
||||
if err != nil {
|
||||
return -1
|
||||
|
|
|
|||
|
|
@ -145,6 +145,35 @@ func TestCache_Age_Good(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCache_NilReceiver_Good(t *testing.T) {
|
||||
var c *cache.Cache
|
||||
var target map[string]string
|
||||
|
||||
if _, err := c.Path("x"); err == nil {
|
||||
t.Fatal("expected Path to fail on nil receiver")
|
||||
}
|
||||
|
||||
if _, err := c.Get("x", &target); err == nil {
|
||||
t.Fatal("expected Get to fail on nil receiver")
|
||||
}
|
||||
|
||||
if err := c.Set("x", map[string]string{"foo": "bar"}); err == nil {
|
||||
t.Fatal("expected Set to fail on nil receiver")
|
||||
}
|
||||
|
||||
if err := c.Delete("x"); err == nil {
|
||||
t.Fatal("expected Delete to fail on nil receiver")
|
||||
}
|
||||
|
||||
if err := c.Clear(); err == nil {
|
||||
t.Fatal("expected Clear to fail on nil receiver")
|
||||
}
|
||||
|
||||
if age := c.Age("x"); age != -1 {
|
||||
t.Fatalf("expected Age to return -1 on nil receiver, got %v", age)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_Delete_Good(t *testing.T) {
|
||||
c, _ := newTestCache(t, "/tmp/cache-delete", time.Minute)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue