- 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
166 lines
4.2 KiB
ReStructuredText
166 lines
4.2 KiB
ReStructuredText
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``.
|