近期某个同事要定期统计当前某个设备的运行状态的情况,按照正常逻辑进行编写了程序,调试验证后可正常使用,但是遇到一个问题:
在调用第三方的接口时,返回504超时导致JSON解析失败的情况,即出现了非JSON响应,故计划增加超时重试、响应格式验证 来规避此问题。

一、封装完整HTTP请求异常处理函数
1、确定函数封装的主要功能
支持常用的GET和POST、超时控制、自动重试
捕获异常分类,解决异常类导入的问题(非JSON返回文案提示,超时记录并重试,错误状态码提示、请求异常重试)
校验HTTP状态码(通过raise_for_status(),2XX为成功,否则跑出HTTPError)
2、封装函数的实现
python
import time,requests
from requests.exceptions import (RequestException,Timeout,HTTPError)
#兼容原生json解析错误
from json.decoder import JSONDecodeError as JsonLibJSONDecodeError
def http_request(url:str,method:str = "POST",params: dict = None,data: dict = None,headers: dict = None,timeout :int = 10,max_retries : int =3,retry_delay: float = 2)->dict:
params = params or {}
data =data or {}
headers =headers or {}
for retry in range(max_retries):
try:
#程序主体部分
if method.upper() == "GET":
response = requests.get(
url=url,
data=params,
headers=headers,
timeout=timeout
)
elif method.upper() == "POST":
response = requests.post(
url=url,
data=params,
json=data,
headers=headers,
timeout=timeout
)
else:
return {
"success": False,
"data": None,
"message": f"不支持的请求方法:{method}"
}
# 校验HTTP状态码(2xx为成功,否则抛出HTTPError)
response.raise_for_status()
# 尝试解析JSON响应
try:
response_data = response.json()
except JsonLibJSONDecodeError:
# 若响应为空或非JSON,返回原始文本(可选)
response_data = response.text
return {
"success": True,
"data": response_data,
"message": "响应非JSON格式,返回原始文本",
"response": response
}
# 请求成功,返回结果
return {
"success": True,
"data": response_data,
"message": "请求成功",
"response": response
}
except Timeout:
#超时异常,记录日志并重试
error_msg = f"⚠️请求超时,第{retry+1}/{max_retries}次重试"
print(f"【ERROR】{error_msg}")
if retry < max_retries:
time.sleep(retry_delay)
else:
return {"success":False,"data":None,"message":f"请求超时,已重试{max_retries}次:{url}"}
except HTTPError as e:
#HTTP状态错误(如504、403。。。)
error_msg = f"HTTP错误:{e.response.status_code}--{e.response.text}"
print(f"【ERROR】{error_msg}")
return {"success":False,"data":None,"message": error_msg,"response":e.response}
except RequestException as e:
# 其他请求异常(连接失败、DNS解析错误等)
error_msg = f"请求异常:{str(e)}"
print(f"[ERROR] {error_msg}")
if retry < max_retries:
time.sleep(retry_delay)
else:
return {
"success": False,
"data": None,
"message": f"请求失败,已重试{max_retries}次:{error_msg}"
}
return {
"success": False,
"data": None,
"message": f"请求失败,超出最大重试次数{max_retries}"
}```
二、编写demo,进行封装函数的验证
```python
def demo(environment):
"""
功能:验证异常处理程序是否可用
:return:
"""
timeline_start_time = deal_time.get_LondonTime(BJ_start_time)
timeline_end_time = deal_time.get_LondonTime(BJ_end_time)
query = {
#此处填写调用接口的参数
}
datas = json.dumps(query)
headers = {
"X-AUTH-SOURCE": "SSO",
"Cookie": deal_token.get_token(environment),
"Content-Type": "application/json; charset=UTF-8",
'Connection': 'close'
}#请根据实际情况进行修改
if environment == "test":
select_url = "对应的url"
if environment == "online":
select_url = "对应的url"
response = http_request(url=select_url, method="POST", params =datas, headers=headers, timeout=10,max_retries =3,retry_delay =2)
if response["data"]["code"] !=0:
#针对token经常过期进行兜底
deal_token.update_token(environment)#该函数根据实际情况进行实现
headers = {
"X-AUTH-SOURCE": "SSO",
"Cookie": deal_token.get_token(environment),
"Content-Type": "application/json; charset=UTF-8",
'Connection': 'close'
}
response = http_request(url=select_url, method="POST", params =datas, headers=headers, timeout=10,max_retries =3,retry_delay =2)
data = response["data"]["data"]
return data
1、验证方式一:通过写错误的url验证HTTP状态码
验证返回结果如下:

2、验证方式二:通过缩短超时时间,验证超时

3、验证方式三:正常请求
通过执行demo,未发生异常时,运行正常。