fix: gracefully handle missing avatar SQLite database

- Return empty list instead of crashing when avatar.db doesn't exist
- Add is_available() check before each endpoint
- 503 status when trying to access unavailable database
This commit is contained in:
stefanfeng
2026-08-06 17:52:01 +08:00
parent bbbc97eb4a
commit 57af1c7db1
2 changed files with 16 additions and 3 deletions
+7 -1
View File
@@ -2,7 +2,7 @@
from fastapi import APIRouter, Query, HTTPException from fastapi import APIRouter, Query, HTTPException
from app.schemas import ApiResponse from app.schemas import ApiResponse
from app.services.avatar_service import avatar_service, get_session from app.services.avatar_service import avatar_service, get_session, is_available
router = APIRouter() router = APIRouter()
@@ -15,6 +15,8 @@ def list_avatars(
status: str = Query(default=None), status: str = Query(default=None),
): ):
"""分页查询所有数字分身""" """分页查询所有数字分身"""
if not is_available():
return ApiResponse(data={"total": 0, "page": page, "page_size": page_size, "items": []})
db = get_session() db = get_session()
try: try:
total, items = avatar_service.list_avatars( total, items = avatar_service.list_avatars(
@@ -35,6 +37,8 @@ def list_avatars(
@router.get("/{avatar_id}") @router.get("/{avatar_id}")
def get_avatar(avatar_id: str): def get_avatar(avatar_id: str):
"""获取单个数字分身详情""" """获取单个数字分身详情"""
if not is_available():
raise HTTPException(status_code=503, detail="数字分身数据库尚未初始化")
db = get_session() db = get_session()
try: try:
data = avatar_service.get_avatar(db, avatar_id) data = avatar_service.get_avatar(db, avatar_id)
@@ -54,6 +58,8 @@ def update_avatar_status(avatar_id: str, body: dict):
status_code=400, status_code=400,
detail="status 必须是 active、inactive 或 training", detail="status 必须是 active、inactive 或 training",
) )
if not is_available():
raise HTTPException(status_code=503, detail="数字分身数据库尚未初始化")
db = get_session() db = get_session()
try: try:
data = avatar_service.update_status(db, avatar_id, status) data = avatar_service.update_status(db, avatar_id, status)
+9 -2
View File
@@ -23,7 +23,8 @@ def _get_engine_and_session():
if not os.path.isabs(db_path): if not os.path.isabs(db_path):
db_path = os.path.abspath(db_path) db_path = os.path.abspath(db_path)
if not os.path.exists(db_path): if not os.path.exists(db_path):
raise FileNotFoundError(f"数字分身数据库不存在: {db_path}") # 数据库不存在时返回 None,由调用方处理
return None, None
_engine = create_engine( _engine = create_engine(
f"sqlite:///{db_path}", f"sqlite:///{db_path}",
connect_args={"check_same_thread": False}, connect_args={"check_same_thread": False},
@@ -32,11 +33,17 @@ def _get_engine_and_session():
return _engine, _SessionLocal() return _engine, _SessionLocal()
def get_session() -> Session: def get_session() -> Optional[Session]:
_, session = _get_engine_and_session() _, session = _get_engine_and_session()
return session return session
def is_available() -> bool:
"""检查数字分身数据库是否可用"""
engine, _ = _get_engine_and_session()
return engine is not None
class AvatarService: class AvatarService:
@staticmethod @staticmethod