release: bump version to 0.3.0
- Refactor Redis backend connection handling and pool management - Update algorithm implementations with improved type annotations - Enhance config loader validation with stricter Pydantic schemas - Improve decorator and middleware error handling - Expand example scripts with better docstrings and usage patterns - Add new 00_basic_usage.py example for quick start - Reorganize examples directory structure - Fix type annotation inconsistencies across core modules - Update dependencies in pyproject.toml
This commit is contained in:
165
docs/api/exceptions.rst
Normal file
165
docs/api/exceptions.rst
Normal file
@@ -0,0 +1,165 @@
|
||||
Exceptions API
|
||||
==============
|
||||
|
||||
Custom exceptions raised by FastAPI Traffic.
|
||||
|
||||
FastAPITrafficError
|
||||
-------------------
|
||||
|
||||
.. py:exception:: FastAPITrafficError
|
||||
|
||||
Base exception for all FastAPI Traffic errors.
|
||||
|
||||
All other exceptions in this library inherit from this class, so you can
|
||||
catch all FastAPI Traffic errors with a single handler:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic.exceptions import FastAPITrafficError
|
||||
|
||||
@app.exception_handler(FastAPITrafficError)
|
||||
async def handle_traffic_error(request: Request, exc: FastAPITrafficError):
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"error": str(exc)},
|
||||
)
|
||||
|
||||
RateLimitExceeded
|
||||
-----------------
|
||||
|
||||
.. py:exception:: RateLimitExceeded(message="Rate limit exceeded", *, retry_after=None, limit_info=None)
|
||||
|
||||
Raised when a rate limit has been exceeded.
|
||||
|
||||
:param message: Error message.
|
||||
:type message: str
|
||||
:param retry_after: Seconds until the client can retry.
|
||||
:type retry_after: float | None
|
||||
:param limit_info: Detailed rate limit information.
|
||||
:type limit_info: RateLimitInfo | None
|
||||
|
||||
.. py:attribute:: message
|
||||
:type: str
|
||||
|
||||
The error message.
|
||||
|
||||
.. py:attribute:: retry_after
|
||||
:type: float | None
|
||||
|
||||
Seconds until the client can retry. May be None if not calculable.
|
||||
|
||||
.. py:attribute:: limit_info
|
||||
:type: RateLimitInfo | None
|
||||
|
||||
Detailed information about the rate limit state.
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi_traffic import RateLimitExceeded
|
||||
|
||||
@app.exception_handler(RateLimitExceeded)
|
||||
async def rate_limit_handler(request: Request, exc: RateLimitExceeded):
|
||||
headers = {}
|
||||
if exc.limit_info:
|
||||
headers = exc.limit_info.to_headers()
|
||||
|
||||
return JSONResponse(
|
||||
status_code=429,
|
||||
content={
|
||||
"error": "rate_limit_exceeded",
|
||||
"message": exc.message,
|
||||
"retry_after": exc.retry_after,
|
||||
},
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
BackendError
|
||||
------------
|
||||
|
||||
.. py:exception:: BackendError(message="Backend operation failed", *, original_error=None)
|
||||
|
||||
Raised when a backend operation fails.
|
||||
|
||||
:param message: Error message.
|
||||
:type message: str
|
||||
:param original_error: The original exception that caused this error.
|
||||
:type original_error: Exception | None
|
||||
|
||||
.. py:attribute:: message
|
||||
:type: str
|
||||
|
||||
The error message.
|
||||
|
||||
.. py:attribute:: original_error
|
||||
:type: Exception | None
|
||||
|
||||
The underlying exception, if any.
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import BackendError
|
||||
|
||||
@app.exception_handler(BackendError)
|
||||
async def backend_error_handler(request: Request, exc: BackendError):
|
||||
# Log the original error for debugging
|
||||
if exc.original_error:
|
||||
logger.error("Backend error: %s", exc.original_error)
|
||||
|
||||
return JSONResponse(
|
||||
status_code=503,
|
||||
content={"error": "service_unavailable"},
|
||||
)
|
||||
|
||||
This exception is raised when:
|
||||
|
||||
- Redis connection fails
|
||||
- SQLite database is locked or corrupted
|
||||
- Any other backend storage operation fails
|
||||
|
||||
ConfigurationError
|
||||
------------------
|
||||
|
||||
.. py:exception:: ConfigurationError
|
||||
|
||||
Raised when there is a configuration error.
|
||||
|
||||
This exception is raised when:
|
||||
|
||||
- Invalid values in configuration files
|
||||
- Missing required configuration
|
||||
- Type conversion failures
|
||||
- Unknown configuration fields
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import ConfigLoader, ConfigurationError
|
||||
|
||||
loader = ConfigLoader()
|
||||
|
||||
try:
|
||||
config = loader.load_rate_limit_config_from_json("config.json")
|
||||
except ConfigurationError as e:
|
||||
print(f"Configuration error: {e}")
|
||||
# Use default configuration
|
||||
config = RateLimitConfig(limit=100, window_size=60)
|
||||
|
||||
Exception Hierarchy
|
||||
-------------------
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
FastAPITrafficError
|
||||
├── RateLimitExceeded
|
||||
├── BackendError
|
||||
└── ConfigurationError
|
||||
|
||||
All exceptions inherit from ``FastAPITrafficError``, which inherits from
|
||||
Python's built-in ``Exception``.
|
||||
Reference in New Issue
Block a user