From 40d8fb742306e606bf8bb1a289e46ae9622f718c Mon Sep 17 00:00:00 2001 From: allen0099 Date: Sat, 26 Sep 2026 18:49:43 +0000 Subject: [PATCH] feat(session): derive SessionError from CacheXError SessionError derived from Exception while StateError derived from CacheXError, so except CacheXError caught state errors but not session errors. SessionError still is an Exception, so existing handlers keep working. Closes #162 --- CHANGELOG.md | 6 ++++++ docs/SESSION.md | 2 ++ fastapi_cachex/session/exceptions.py | 10 ++++++++-- i18n/zh-TW/docs/SESSION.md | 2 +- tests/session/test_manager.py | 12 ++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec316c..cd96a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,12 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. summaries with their issue links, grouped as in the changelog, and links to the full entries on the documentation site. The changelog itself keeps the details. +- **`SessionError` derives from `CacheXError`.** It derived from `Exception`, + while `StateError` already derived from `CacheXError`, so `except CacheXError` + caught state errors but not session errors. Handlers for `SessionError` or + `Exception` keep working. A `try` block that lists `except CacheXError` + before `except SessionError` now takes the `CacheXError` branch for session + errors. ([#162](https://github.com/allen0099/FastAPI-CacheX/issues/162)) ### Deprecated diff --git a/docs/SESSION.md b/docs/SESSION.md index 20eee69..32d2340 100644 --- a/docs/SESSION.md +++ b/docs/SESSION.md @@ -645,6 +645,8 @@ be sent back to the client. `get_session()` raises a `SessionError` subclass on failure: `SessionTokenError` (malformed token), `SessionSecurityError` (bad signature or binding mismatch), `SessionNotFoundError`, `SessionInvalidError` (session not active) or `SessionExpiredError` (TTL or absolute timeout exceeded). +Since 0.3.8, `SessionError` derives from `CacheXError`, so `except CacheXError` +catches session errors too. Every method with its signature is in the generated [Session API reference](api/session.md). diff --git a/fastapi_cachex/session/exceptions.py b/fastapi_cachex/session/exceptions.py index 32a2304..4c71b4b 100644 --- a/fastapi_cachex/session/exceptions.py +++ b/fastapi_cachex/session/exceptions.py @@ -1,8 +1,14 @@ """Session-related exceptions.""" +from fastapi_cachex.exceptions import CacheXError -class SessionError(Exception): - """Base exception for session errors.""" + +class SessionError(CacheXError): + """Base exception for session errors. + + Derives from ``CacheXError`` since 0.3.8, like ``StateError``, so + ``except CacheXError`` also catches session errors. + """ class SessionNotFoundError(SessionError): diff --git a/i18n/zh-TW/docs/SESSION.md b/i18n/zh-TW/docs/SESSION.md index 6843232..dc6fc84 100644 --- a/i18n/zh-TW/docs/SESSION.md +++ b/i18n/zh-TW/docs/SESSION.md @@ -534,7 +534,7 @@ session, new_token = await manager.regenerate_session_id(session) ## SessionManager 概覽 {#sessionmanager-at-a-glance} -`SessionManager(backend, config, token_serializer=None)` 處理整個生命週期:`create_session()`/`create_anonymous_session()` 回傳 `(session, token)`;`get_session()` 回傳 `(session, renewed_token)`,其中 `renewed_token` 只有在滑動過期更新了權杖時才會有值,並應傳回給用戶端。`get_session()` 失敗時會拋出 `SessionError` 的子類別:`SessionTokenError`(權杖格式錯誤)、`SessionSecurityError`(簽章錯誤或綁定不符)、`SessionNotFoundError`、`SessionInvalidError`(Session 不是啟用狀態)或 `SessionExpiredError`(超過 TTL 或絕對逾時)。 +`SessionManager(backend, config, token_serializer=None)` 處理整個生命週期:`create_session()`/`create_anonymous_session()` 回傳 `(session, token)`;`get_session()` 回傳 `(session, renewed_token)`,其中 `renewed_token` 只有在滑動過期更新了權杖時才會有值,並應傳回給用戶端。`get_session()` 失敗時會拋出 `SessionError` 的子類別:`SessionTokenError`(權杖格式錯誤)、`SessionSecurityError`(簽章錯誤或綁定不符)、`SessionNotFoundError`、`SessionInvalidError`(Session 不是啟用狀態)或 `SessionExpiredError`(超過 TTL 或絕對逾時)。從 0.3.8 起,`SessionError` 繼承自 `CacheXError`,因此 `except CacheXError` 也會捕捉 Session 錯誤。 每個方法及其簽名請見自動產生的 [Session API 參考](https://fastapi-cachex.readthedocs.io/en/latest/api/session/)(英文)。 diff --git a/tests/session/test_manager.py b/tests/session/test_manager.py index 92918af..265aa13 100644 --- a/tests/session/test_manager.py +++ b/tests/session/test_manager.py @@ -11,6 +11,7 @@ from pydantic import SecretStr from fastapi_cachex.backends.memory import MemoryBackend +from fastapi_cachex.exceptions import CacheXError from fastapi_cachex.session.config import SessionConfig from fastapi_cachex.session.exceptions import SessionExpiredError from fastapi_cachex.session.exceptions import SessionInvalidError @@ -120,6 +121,17 @@ async def test_get_invalid_token(manager: SessionManager) -> None: await manager.get_session("invalid-token") +@pytest.mark.asyncio +async def test_session_errors_are_caught_as_cachex_errors( + manager: SessionManager, +) -> None: + """Test a session error is caught by ``except CacheXError`` (#162).""" + with pytest.raises(CacheXError) as exc_info: + await manager.get_session("invalid-token") + + assert isinstance(exc_info.value, SessionTokenError) + + @pytest.mark.asyncio async def test_get_nonexistent_session(manager: SessionManager) -> None: """Test getting nonexistent session."""