保存请求失败返回500

调整表结构
This commit is contained in:
mark.tian
2025-12-04 08:14:21 +08:00
parent f1f694bd63
commit 6ac998ebdf
5 changed files with 158 additions and 79 deletions

View File

@@ -8,15 +8,49 @@ from fastapi import HTTPException
import httpx
import asyncio
from typing import Dict, Any, Optional
import json
from app.database import CallbackData, ExternalApiLog
from app.database import CallbackFailureData, ExternalApiLog, CallbackFailureLog
from app.config import settings
from app.logger import get_logger
logger = get_logger("external_api_processor")
async def get_callback_log_data(
db: AsyncSession,
callback_log_id: int
) -> tuple[bool, Optional[Dict[str, Any]], Optional[str]]:
"""
从回调日志中获取请求头和请求体
Args:
db: 数据库会话
callback_log_id: 回调日志ID
Returns:
tuple[查询是否成功, 请求头字典, 请求体字符串]
"""
try:
# 查询回调日志
query = select(CallbackFailureLog).where(CallbackFailureLog.id == callback_log_id)
result = await db.execute(query)
callback_log = result.scalar_one_or_none()
if not callback_log:
logger.warning(f"⚠️ 未找到回调日志记录,ID: {callback_log_id}")
return False, None, None
logger.info(f"✅ 成功获取回调日志,ID: {callback_log_id}")
# 返回查询成功标识、请求头和请求体
return True, callback_log.request_headers, callback_log.request_body
except Exception as e:
logger.error(f"❌ 获取回调日志失败,ID: {callback_log_id}, 错误: {e}", exc_info=True)
return False, None, None
async def check_phone_number_threshold(
db: AsyncSession,
phone_number: str
@@ -33,8 +67,8 @@ async def check_phone_number_threshold(
"""
try:
# 查询手机号在数据库中出现的次数
count_query = select(func.count(CallbackData.id)).where(
CallbackData.phone_number == phone_number
count_query = select(func.count(CallbackFailureData.id)).where(
CallbackFailureData.phone_number == phone_number
)
result = await db.execute(count_query)
phone_count = result.scalar() or 0
@@ -57,7 +91,7 @@ async def check_phone_number_threshold(
async def log_external_api_request(
db: AsyncSession,
callback_logs_id: int,
callback_failure_log_id: int,
request_url: str,
request_headers: Dict[str, Any],
request_body: Dict[str, Any],
@@ -69,7 +103,7 @@ async def log_external_api_request(
"""记录外部API请求日志"""
try:
api_log = ExternalApiLog(
callback_logs_id=callback_logs_id,
callback_failure_log_id=callback_failure_log_id,
request_url=request_url,
request_headers=request_headers,
request_body=request_body,
@@ -92,7 +126,7 @@ async def call_external_api_with_retry(
db: AsyncSession,
request_body: Dict[str, Any],
max_retries: int = None,
callback_logs_id: int = None
callback_failure_log_id: int = None
) -> tuple[bool, int]:
"""
调用外部API并支持重试机制
@@ -101,7 +135,7 @@ async def call_external_api_with_retry(
db: 数据库会话
request_body: 请求体
max_retries: 最大重试次数
callback_logs_id: 回调日志ID
callback_failure_log_id: 回调失败日志ID
Returns:
tuple[是否成功, 实际重试次数]
@@ -132,7 +166,7 @@ async def call_external_api_with_retry(
# 记录每次尝试的结果
await log_external_api_request(
db=db,
callback_logs_id=callback_logs_id,
callback_failure_log_id=callback_failure_log_id,
request_url=settings.external_api_url,
request_headers=headers,
request_body=request_body,
@@ -172,26 +206,37 @@ async def call_external_api_with_retry(
async def process_external_api_call(
db: AsyncSession,
callback_data: dict,
callback_log_id: int,
siteId: str,
callback_log_id: int
):
"""
异步调用外部接口
Args:
db: 数据库会话
callback_data: 回调数据
siteId: 站点ID
callback_log_id: 回调日志ID
siteId: 站点ID
Returns:
None: 无返回值
"""
success, request_headers_json, request_body_json = await get_callback_log_data(db, callback_log_id)
if not success:
# 查询失败,处理错误情况
logger.error(f"获取回调日志数据失败:{callback_log_id}")
return
# 查询成功,可以使用获取到的数据
logger.info(f"📋 请求头: {callback_log_id}|{request_headers_json}")
logger.info(f"📄 请求体: {callback_log_id}|{request_body_json}")
request_headers = json.loads(request_headers_json)
request_body = json.loads(request_body_json)
# 提取所有手机号并去重
phone_numbers_set = set()
data_list = callback_data.get('data', [])
data_list = request_body.get('data', [])
for item in data_list:
number_data = item.get('number_data', {})
phone_number = number_data.get('number')
@@ -223,12 +268,11 @@ async def process_external_api_call(
# 手机号出现的次数少于settings.count_threshold,调用外部API
# 调用外部API并支持重试
request_body = callback_data
success, retry_count = await call_external_api_with_retry(
db=db,
request_body=request_body,
max_retries=settings.external_api_retry_max,
callback_logs_id=callback_log_id
callback_failure_log_id=callback_log_id
)
if success: