CoolFace
Apppublic

wqngxiwn/database

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
error_handling.py137 linesDownload Raw Back to root
1import requests2import logging3import asyncio4from fastapi import HTTPException, status5from app.utils.logging import format_log_message6 7logger = logging.getLogger("my_logger")8 9def handle_gemini_error(error, current_api_key, key_manager) -> str:10    if isinstance(error, requests.exceptions.HTTPError):11        status_code = error.response.status_code12        if status_code == 400:13            try:14                error_data = error.response.json()15                if 'error' in error_data:16                    if error_data['error'].get('code') == "invalid_argument":17                        error_message = "无效的 API 密钥"18                        extra_log_invalid_key = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}19                        log_msg = format_log_message('ERROR', f"{current_api_key[:8]} ... {current_api_key[-3:]} → 无效,可能已过期或被删除", extra=extra_log_invalid_key)20                        logger.error(log_msg)21                        # key_manager.blacklist_key(current_api_key)22                        23                        return error_message24                    error_message = error_data['error'].get(25                        'message', 'Bad Request')26                    extra_log_400 = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}27                    log_msg = format_log_message('WARNING', f"400 错误请求: {error_message}", extra=extra_log_400)28                    logger.warning(log_msg)29                    return f"400 错误请求: {error_message}"30            except ValueError:31                error_message = "400 错误请求:响应不是有效的JSON格式"32                extra_log_400_json = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}33                log_msg = format_log_message('WARNING', error_message, extra=extra_log_400_json)34                logger.warning(log_msg)35                return error_message36 37        elif status_code == 429:38            error_message = "API 密钥配额已用尽或其他原因"39            extra_log_429 = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}40            log_msg = format_log_message('WARNING', f"{current_api_key[:8]} ... {current_api_key[-3:]} → 429 官方资源耗尽或其他原因", extra=extra_log_429)41            logger.warning(log_msg)42            # key_manager.blacklist_key(current_api_key)43             44            return error_message45 46        elif status_code == 403:47            error_message = "权限被拒绝"48            extra_log_403 = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}49            log_msg = format_log_message('ERROR', f"{current_api_key[:8]} ... {current_api_key[-3:]} → 403 权限被拒绝", extra=extra_log_403)50            logger.error(log_msg)51            # key_manager.blacklist_key(current_api_key)52            53            return error_message54        elif status_code == 500:55            error_message = "服务器内部错误"56            extra_log_500 = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}57            log_msg = format_log_message('WARNING', f"{current_api_key[:8]} ... {current_api_key[-3:]} → 500 服务器内部错误", extra=extra_log_500)58            logger.warning(log_msg)59            60            return "Gemini API 内部错误"61 62        elif status_code == 503:63            error_message = "服务不可用"64            extra_log_503 = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}65            log_msg = format_log_message('WARNING', f"{current_api_key[:8]} ... {current_api_key[-3:]} → 503 服务不可用", extra=extra_log_503)66            logger.warning(log_msg)67            68            return "Gemini API 服务不可用"69        else:70            error_message = f"未知错误: {status_code}"71            extra_log_other = {'key': current_api_key[:8], 'status_code': status_code, 'error_message': error_message}72            log_msg = format_log_message('WARNING', f"{current_api_key[:8]} ... {current_api_key[-3:]} → {status_code} 未知错误", extra=extra_log_other)73            logger.warning(log_msg)74            75            return f"未知错误/模型不可用: {status_code}"76 77    elif isinstance(error, requests.exceptions.ConnectionError):78        error_message = "连接错误"79        log_msg = format_log_message('WARNING', error_message, extra={'error_message': error_message})80        logger.warning(log_msg)81        return error_message82 83    elif isinstance(error, requests.exceptions.Timeout):84        error_message = "请求超时"85        log_msg = format_log_message('WARNING', error_message, extra={'error_message': error_message})86        logger.warning(log_msg)87        return error_message88    else:89        error_message = f"发生未知错误: {error}"90        log_msg = format_log_message('ERROR', error_message, extra={'error_message': error_message})91        logger.error(log_msg)92        return error_message93 94def translate_error(message: str) -> str:95    if "quota exceeded" in message.lower():96        return "API 密钥配额已用尽"97    if "invalid argument" in message.lower():98        return "无效参数"99    if "internal server error" in message.lower():100        return "服务器内部错误"101    if "service unavailable" in message.lower():102        return "服务不可用"103    return message104 105async def handle_api_error(e, api_key, key_manager, request_type, model, retry_count=0):106    """统一处理API错误,对500和503错误实现自动重试机制"""107    error_detail = handle_gemini_error(e, api_key, key_manager)108    109    # 处理500和503服务器错误110    if isinstance(e, requests.exceptions.HTTPError) and ('500' in str(e) or '503' in str(e)):111        status_code = '500' if '500' in str(e) else '503'112        113        # 最多重试3次114        if retry_count < 3:115            wait_time = min(1 * (2 ** retry_count), 16)  # RETRY_DELAY=1, MAX_RETRY_DELAY=16116            log_msg = format_log_message('WARNING', f"Gemini服务器错误({status_code}),等待{wait_time}秒后重试 ({retry_count+1}/3)",117                extra={'key': api_key[:8], 'request_type': request_type, 'model': model, 'status_code': int(status_code)})118            logger.warning(log_msg)119            120            # 等待后返回重试信号121            await asyncio.sleep(wait_time)122            return {'should_retry': True, 'error': error_detail, 'remove_cache': False}123        124        # 重试次数用尽,直接返回错误状态码125        log_msg = format_log_message('ERROR', f"服务器错误({status_code})重试{retry_count}次后仍然失败",126            extra={'key': api_key[:8], 'request_type': request_type, 'model': model, 'status_code': int(status_code)})127        logger.error(log_msg)128        129        # 不建议切换密钥,直接抛出HTTP异常130        raise HTTPException(status_code=int(status_code),131                          detail=f"Gemini API 服务器错误({status_code}),请稍后重试")132    133    # 对于其他错误,返回切换密钥的信号134    log_msg = format_log_message('ERROR', f"API错误: {error_detail}",135        extra={'key': api_key[:8], 'request_type': request_type, 'model': model, 'error_message': error_detail})136    logger.error(log_msg)137    return {'should_retry': False, 'should_switch_key': True, 'error': error_detail, 'remove_cache': True}