feat: Automatically retry up to three times when encountering a ServerDisconnectedError during API requests

This commit is contained in:
LWR
2023-05-30 00:47:19 +08:00
parent 93df2cd8a1
commit 02da461229
+51 -41
View File
@@ -9,10 +9,10 @@ import re
from typing import Any, Union, Dict from typing import Any, Union, Dict
import aiohttp import aiohttp
from aiohttp import TCPConnector from aiohttp import TCPConnector, ServerDisconnectedError
from ..exception import ResponseCodeException, ResponseException, NetworkException
from .Credential import Credential from .Credential import Credential
from ..exception import ResponseCodeException, ResponseException, NetworkException
__session_pool = {} __session_pool = {}
@@ -111,55 +111,65 @@ async def request(method: str,
session = get_session() session = get_session()
async with session.request(**config) as resp: for i in range(3):
# 检查状态码
try: try:
resp.raise_for_status() async with session.request(**config) as resp:
except aiohttp.ClientResponseError as e:
raise NetworkException(e.status, e.message)
# 检查响应头 Content-Length # 检查状态码
content_length = resp.headers.get("content-length") try:
if content_length and int(content_length) == 0: resp.raise_for_status()
return None except aiohttp.ClientResponseError as e:
raise NetworkException(e.status, e.message)
# 检查响应头 Content-Type # 检查响应头 Content-Length
content_type = resp.headers.get("content-type") content_length = resp.headers.get("content-length")
if content_length and int(content_length) == 0:
return None
# 不是 application/json # 检查响应头 Content-Type
if content_type.lower().index("application/json") == -1: content_type = resp.headers.get("content-type")
raise ResponseException("响应不是 application/json 类型")
raw_data = await resp.text() # 不是 application/json
resp_data: dict if content_type.lower().index("application/json") == -1:
raise ResponseException("响应不是 application/json 类型")
if 'callback' in params: raw_data = await resp.text()
# JSONP 请求 resp_data: dict
resp_data = json.loads(
re.match("^.*?({.*}).*$", raw_data, re.S).group(1))
else:
# JSON
resp_data = json.loads(raw_data)
# 检查 code if 'callback' in params:
code = resp_data.get("code", None) # JSONP 请求
resp_data = json.loads(
re.match("^.*?({.*}).*$", raw_data, re.S).group(1))
else:
# JSON
resp_data = json.loads(raw_data)
if code is None: # 检查 code
raise ResponseCodeException(-1, "API 返回数据未含 code 字段", resp_data) code = resp_data.get("code", None)
if code != 0: if code is None:
msg = resp_data.get('msg', None) raise ResponseCodeException(-1, "API 返回数据未含 code 字段", resp_data)
if msg is None:
msg = resp_data.get('message', None)
if msg is None:
msg = "接口未返回错误信息"
raise ResponseCodeException(code, msg, resp_data)
real_data = resp_data.get("data", None) if code != 0:
if real_data is None: # 加载错误,请稍后再试
real_data = resp_data.get("result", None) if code == 4101131:
return real_data await asyncio.sleep(10)
continue
msg = resp_data.get('msg', None)
if msg is None:
msg = resp_data.get('message', None)
if msg is None:
msg = "接口未返回错误信息"
raise ResponseCodeException(code, msg, resp_data)
real_data = resp_data.get("data", None)
if real_data is None:
real_data = resp_data.get("result", None)
return real_data
except ServerDisconnectedError:
await asyncio.sleep(0.5)
continue
def get_session() -> aiohttp.ClientSession: def get_session() -> aiohttp.ClientSession: