From 47125aaf852ebdd56c873298c421fbc77b7b14df Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Sat, 16 May 2026 15:33:07 -0400 Subject: [PATCH] ping returns ErrNoServers when no servers are configured A client built via New() without addresses (or after they're all removed via the ServerList) used to report Ping success because selector.Each iterated over an empty list and returned nil. That disagreed with every other client method, which surfaces ErrNoServers in the same situation, and let callers think they had a working client when nothing was reachable. Track whether any callback fired and return ErrNoServers when none did. Fixes #179. Signed-off-by: Charlie Tonneslan --- memcache/memcache.go | 16 ++++++++++++++-- memcache/memcache_test.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/memcache/memcache.go b/memcache/memcache.go index 6f48caa..fd7e1d9 100644 --- a/memcache/memcache.go +++ b/memcache/memcache.go @@ -779,9 +779,21 @@ func (c *Client) getAndTouchFromAddr(addr net.Addr, key string, expiration int32 } // Ping checks all instances if they are alive. Returns error if any -// of them is down. +// of them is down, or ErrNoServers if the client has no servers +// configured. func (c *Client) Ping() error { - return c.selector.Each(c.ping) + pinged := false + err := c.selector.Each(func(addr net.Addr) error { + pinged = true + return c.ping(addr) + }) + if err != nil { + return err + } + if !pinged { + return ErrNoServers + } + return nil } // Increment atomically increments key by delta. The return value is diff --git a/memcache/memcache_test.go b/memcache/memcache_test.go index a0fa746..36febbb 100644 --- a/memcache/memcache_test.go +++ b/memcache/memcache_test.go @@ -502,3 +502,14 @@ func TestScanGetResponseLine(t *testing.T) { }) } } + +// Regression for #179. A client built with zero servers used to report +// Ping success because Each iterates over an empty list. Other +// operations on the same client return ErrNoServers, so Ping should +// surface the same signal. +func TestPingNoServers(t *testing.T) { + c := New() + if err := c.Ping(); err != ErrNoServers { + t.Fatalf("Ping() = %v, want ErrNoServers", err) + } +}