Skip to content

feat: one exception family for an invalid ttl (#337) - #463

Merged
allen0099 merged 1 commit into
masterfrom
claude/charming-gauss-dyvsj7
Oct 14, 2026
Merged

allen0099 merged 1 commit into
masterfrom
claude/charming-gauss-dyvsj7

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Fixes #337

Summary

An invalid ttl raised CacheXError in @cache, but TypeError or ValueError in the backends, CacheManager and CacheLock. Code validating a user-supplied TTL had to catch all three.

This PR follows the issue's proposal: a CacheXError subclass that keeps the built-in bases, so no existing except clause breaks.

CacheXError
└── InvalidTTLError          catch this for any invalid ttl
    ├── TTLTypeError(InvalidTTLError, TypeError)
    └── TTLValueError(InvalidTTLError, ValueError)

These now raise the new classes:

  • validate_ttl(), and therefore every backend, CacheManager, CacheLock and @cached
  • @cache's check on ttl and stale_ttl
  • the Memcached check for an expiry after 2038-01-19

Old except clauses keep working:

  • except TypeError and except ValueError around backend, manager or lock calls still catch.
  • except CacheXError around @cache still catches.
  • The only new behaviour: an except ValueError around @cache(ttl=-1) now also catches. Nothing changes otherwise.

Other changes:

  • All three names are exported from fastapi_cachex and documented by the API reference (::: fastapi_cachex.exceptions).
  • "TTL values" in BACKENDS.md and the ttl=0 note in HTTP_CACHING.md are updated in English and zh-TW, with an except InvalidTTLError example.
  • validate_delta (the counter delta, not a TTL) is unchanged.

The docstrings and docs say "before 0.5.1", assuming this ships in the next patch release. If you release it as 0.6.0, they need changing.

Checklist

  • The issue above is assigned to me (maintainer's own issue)
  • Tests under tests/ cover the change. tests/test_ttl_errors.py checks each entry point (backend set, CacheManager and its set, CacheLock, @cached, @cache ttl/stale_ttl, the Memcached 2038 check) for the exact class and both bases. Reverting one raise to TypeError fails 12 tests, and reverting @cache's to CacheXError fails 2.
  • A changelog fragment: changelog.d/337.added.md
  • uv run pre-commit run --all-files and uv run pytest --cov pass: 1243 passed, 192 skipped, 92.90% coverage. So do mypy strict, mypy tests, mypy scripts and both zensical build --strict runs.

Generated by Claude Code

An invalid ttl raised CacheXError in @cache but TypeError or ValueError
in the backends, CacheManager and CacheLock, so code validating a
user-supplied ttl had to catch all three.

Add InvalidTTLError (a CacheXError) with two subclasses that keep the
built-in bases: TTLTypeError (also a TypeError) and TTLValueError (also
a ValueError). validate_ttl, @cache's ttl/stale_ttl check and the
Memcached 2038 expiry check raise them, so every entry point raises the
same classes and every existing except clause keeps catching them.
Exported from fastapi_cachex and documented under TTL values.

Closes #337
@allen0099
allen0099 merged commit 36bcf8d into master Oct 14, 2026
14 checks passed
@allen0099
allen0099 deleted the claude/charming-gauss-dyvsj7 branch October 14, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An invalid ttl raises CacheXError in @cache but TypeError/ValueError in backends and CacheManager

1 participant