feat: Automatically retry up to three times when encountering a ServerDisconnectedError during API requests
This commit is contained in:
+51
-41
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user