Split out of #228 (fixed for @cache in #259).
Problem
When a backend's transport fails, each backend raises its own client exceptions:
- Redis raises
redis.exceptions.ConnectionError / TimeoutError.
- Memcached raises pymemcache or socket errors.
- The memory backend never fails this way.
A caller that wants to handle "the cache is down" has to know which backend is configured and import that client library's exceptions. That is awkward for CacheManager, StateManager, CacheLock and session code, which still let backend errors propagate. #259 sidesteps the question in @cache by catching Exception.
Proposal
- Add
BackendUnavailableError(CacheXError) in fastapi_cachex/exceptions.py.
- Have the Redis and Memcached backends translate transport-level failures into it and chain the original exception (
raise ... from e). Transport-level failures are connection refused/reset, timeouts and a server out of rotation.
- Leave errors that are not about availability as they are: bad input, serialization, and the existing
CacheXError cases.
- Document which operations can raise it. Consider narrowing
@cache's fail-open catch to it plus the known storage-rejection cases.
Open questions
- Is this a breaking change? Code that catches
redis.exceptions.ConnectionError today would stop catching it unless BackendUnavailableError also subclasses the original types, which is not possible across backends. That probably means the 0.4.0 milestone, or a transition period in which the new error is raised alongside a deprecation note.
- Should "item too large" (Memcached
object too large for cache) be a separate CacheXError subclass rather than an availability error?
Split out of #228 (fixed for
@cachein #259).Problem
When a backend's transport fails, each backend raises its own client exceptions:
redis.exceptions.ConnectionError/TimeoutError.A caller that wants to handle "the cache is down" has to know which backend is configured and import that client library's exceptions. That is awkward for
CacheManager,StateManager,CacheLockand session code, which still let backend errors propagate. #259 sidesteps the question in@cacheby catchingException.Proposal
BackendUnavailableError(CacheXError)infastapi_cachex/exceptions.py.raise ... from e). Transport-level failures are connection refused/reset, timeouts and a server out of rotation.CacheXErrorcases.@cache's fail-open catch to it plus the known storage-rejection cases.Open questions
redis.exceptions.ConnectionErrortoday would stop catching it unlessBackendUnavailableErroralso subclasses the original types, which is not possible across backends. That probably means the 0.4.0 milestone, or a transition period in which the new error is raised alongside a deprecation note.object too large for cache) be a separateCacheXErrorsubclass rather than an availability error?