mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
fix(persistence): separate retryable rejection errors (#6423)
This commit is contained in:
+31
-12
@@ -18,14 +18,16 @@ from app.api.response import (
|
||||
ResponseAPIRouter,
|
||||
)
|
||||
from app.factory import (
|
||||
database_worker_overloaded_handler,
|
||||
localized_http_exception_handler,
|
||||
localized_unhandled_exception_handler,
|
||||
localized_validation_exception_handler,
|
||||
persistence_unavailable_handler,
|
||||
)
|
||||
from app.schemas.exception import (
|
||||
AgentChatPersistenceUnavailableError,
|
||||
DatabaseWorkerClosedError,
|
||||
DatabaseWorkerOverloadedError,
|
||||
PersistenceUnavailableError,
|
||||
)
|
||||
from app.runtime.localization import LocaleHelper
|
||||
from app.runtime.config import settings
|
||||
@@ -67,12 +69,8 @@ def api_app() -> FastAPI:
|
||||
app.router.route_class = ResponseAPIRoute
|
||||
app.add_exception_handler(HTTPException, localized_http_exception_handler)
|
||||
app.add_exception_handler(
|
||||
DatabaseWorkerOverloadedError,
|
||||
database_worker_overloaded_handler,
|
||||
)
|
||||
app.add_exception_handler(
|
||||
DatabaseWorkerClosedError,
|
||||
database_worker_overloaded_handler,
|
||||
PersistenceUnavailableError,
|
||||
persistence_unavailable_handler,
|
||||
)
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
|
||||
@@ -137,6 +135,11 @@ def api_app() -> FastAPI:
|
||||
"""模拟数据库 worker 在关闭态拒绝新任务。"""
|
||||
raise DatabaseWorkerClosedError("worker closed")
|
||||
|
||||
@app.get("/agent-chat-persistence-unavailable")
|
||||
async def get_agent_chat_persistence_unavailable() -> None:
|
||||
"""模拟 AgentChat 自身 admission 拒绝新写入。"""
|
||||
raise AgentChatPersistenceUnavailableError("agent persistence full")
|
||||
|
||||
@app.get("/native", response_model=None)
|
||||
async def get_native_response() -> dict[str, bool]:
|
||||
"""返回显式旁路的原生 JSON 协议。"""
|
||||
@@ -247,14 +250,30 @@ async def test_database_worker_closed_is_retryable_service_unavailable(
|
||||
}
|
||||
|
||||
|
||||
def test_create_app_registers_closed_database_worker_handler() -> None:
|
||||
"""生产组合根必须为 worker 关闭态登记 503 处理器。"""
|
||||
async def test_agent_chat_persistence_rejection_is_retryable_service_unavailable(
|
||||
api_app: FastAPI,
|
||||
) -> None:
|
||||
"""AgentChat 自身 admission 拒绝也应返回可重试的 503。"""
|
||||
async with make_client(api_app) as client:
|
||||
response = await client.get("/agent-chat-persistence-unavailable")
|
||||
|
||||
assert response.status_code == 503
|
||||
assert response.headers["retry-after"] == "1"
|
||||
assert response.json() == {
|
||||
"success": False,
|
||||
"message": "服务当前繁忙,请稍后重试",
|
||||
"data": None,
|
||||
}
|
||||
|
||||
|
||||
def test_create_app_registers_persistence_unavailable_handler() -> None:
|
||||
"""生产组合根必须为持久化暂不可用登记统一 503 处理器。"""
|
||||
from app.factory import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
assert app.exception_handlers[DatabaseWorkerClosedError] is (
|
||||
database_worker_overloaded_handler
|
||||
assert app.exception_handlers[PersistenceUnavailableError] is (
|
||||
persistence_unavailable_handler
|
||||
)
|
||||
|
||||
|
||||
@@ -283,7 +302,7 @@ async def test_database_worker_overload_preserves_retry_after_for_native_protoco
|
||||
"client": ("testclient", 123),
|
||||
"root_path": "",
|
||||
}
|
||||
response = await database_worker_overloaded_handler(
|
||||
response = await persistence_unavailable_handler(
|
||||
Request(scope),
|
||||
DatabaseWorkerOverloadedError("worker full"),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user