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."""