在调用京东京东商品详情 API 接口时,错误和异常处理是确保程序稳定性的关键。以下是一些常见的错误处理策略和实现方式:
常见的错误类型
网络相关错误:连接超时、网络中断、DNS 解析失败等
API 服务错误:服务暂时不可用、服务器内部错误
认证授权错误:AppKey 无效、签名错误、权限不足
参数错误:参数缺失、参数格式不正确
业务错误:商品不存在、接口调用频率超限
错误处理实现示例
下面是一个 Python 示例,展示如何全面处理调用京东 API 时可能出现的错误:
python
运行
import requestsimport timeimport hashlibimport jsonfrom requests.exceptions import (
ConnectionError,
Timeout,
HTTPError,
RequestException)class JDAPIError(Exception):
"""京东API调用异常基类"""
passclass AuthError(JDAPIError):
"""认证相关错误"""
passclass ParameterError(JDAPIError):
"""参数相关错误"""
passclass BusinessError(JDAPIError):
"""业务逻辑错误"""
passclass JDClient:
def __init__(self, app_key, app_secret, api_url):
self.app_key = app_key
self.app_secret = app_secret
self.api_url = api_url
self.timeout = 10 # 超时时间,单位秒
self.max_retries = 3 # 最大重试次数
self.retry_delay = 1 # 重试延迟,单位秒
def _generate_sign(self, params):
"""生成签名"""
# 按照京东API要求生成签名
sorted_params = sorted(params.items(), key=lambda x: x[0])
sign_str = self.app_secret for k, v in sorted_params:
sign_str += f"{k}{v}"
sign_str += self.app_secret return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
def get_product_detail(self, product_id):
"""获取商品详情"""
params = {
"app_key": self.app_key,
"method": "jd.union.open.goods.detail.query", # 假设的接口方法
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"format": "json",
"v": "1.0",
"param_json": json.dumps({"skuId": product_id})
}
# 生成签名
params["sign"] = self._generate_sign(params)
# 带重试机制的请求
for retry in range(self.max_retries):
try:
response = requests.get(
self.api_url,
params=params,
timeout=self.timeout )
response.raise_for_status() # 抛出HTTP错误
result = response.json()
# 处理API返回的错误码
if "error_response" in result:
error = result["error_response"]
error_code = error.get("code")
error_msg = error.get("msg", "未知错误")
# 根据错误码分类处理
if error_code in [1000, 1001, 1002]: # 假设这些是认证错误码
raise AuthError(f"认证错误({error_code}): {error_msg}")
elif error_code in [2000, 2001]: # 参数错误码
raise ParameterError(f"参数错误({error_code}): {error_msg}")
elif error_code in [3000, 3001, 3002]: # 业务错误码
raise BusinessError(f"业务错误({error_code}): {error_msg}")
else:
raise JDAPIError(f"API错误({error_code}): {error_msg}")
return result
except (ConnectionError, Timeout) as e:
# 网络错误,可重试
if retry < self.max_retries - 1:
time.sleep(self.retry_delay * (retry + 1)) # 指数退避
continue
raise JDAPIError(f"网络错误: {str(e)}")
except HTTPError as e:
# HTTP状态码错误
status_code = e.response.status_code if 500 <= status_code < 600 and retry < self.max_retries - 1:
# 服务器错误,可重试
time.sleep(self.retry_delay * (retry + 1))
continue
raise JDAPIError(f"HTTP错误({status_code}): {str(e)}")
except RequestException as e:
# 其他请求相关错误
raise JDAPIError(f"请求错误: {str(e)}")
raise JDAPIError("达到最大重试次数,请求失败")# 使用示例if __name__ == "__main__":
app_key = "your_app_key"
app_secret = "your_app_secret"
api_url = "https://api.jd.com/routerjson"
client = JDClient(app_key, app_secret, api_url)
try:
product_id = "100012345678"
detail = client.get_product_detail(product_id)
print(f"成功获取商品详情: {json.dumps(detail, ensure_ascii=False, indent=2)}")
except AuthError as e:
print(f"认证失败: {e}")
# 可能需要重新获取令牌或检查密钥
except ParameterError as e:
print(f"参数错误: {e}")
# 检查请求参数
except BusinessError as e:
print(f"业务处理失败: {e}")
# 根据业务逻辑处理,如记录不存在的商品ID
except JDAPIError as e:
print(f"API调用失败: {e}")
except Exception as e:
print(f"发生未知错误: {e}")关键处理策略
异常分类:将异常分为不同类型,便于针对性处理
重试机制:对可恢复的错误(如网络波动、服务器临时错误)进行有限次数的重试
指数退避:重试间隔随次数增加而延长,避免加重服务器负担
错误码解析:根据京东 API 返回的错误码进行精细化处理
资源释放:确保在发生错误时也能正确释放资源
日志记录:实际应用中应添加详细的日志记录,便于问题排查
处理错误时应根据具体的业务场景调整策略,例如对于关键业务可能需要更复杂的重试机制和告警通知。