如何将Requests异常转换为Django REST Framework可处理的API异常?
解决方案:将Requests异常转换为DRF可处理异常
有没有现成工具包?
目前没有专门做这个转换的主流工具包,这类需求场景比较具体,开发者大多会自己实现转换逻辑,灵活性更高。
最佳实践实现方案
1. 自定义DRF异常类
先定义继承APIException的异常类,对应不同的Requests异常场景:
from rest_framework.exceptions import APIException class ThirdPartyAPIError(APIException): status_code = 503 default_detail = "第三方服务暂时不可用" default_code = "third_party_unavailable" class ThirdPartyTimeoutError(ThirdPartyAPIError): default_detail = "第三方服务请求超时" default_code = "third_party_timeout" class ThirdPartyConnectionError(ThirdPartyAPIError): default_detail = "无法连接到第三方服务" default_code = "third_party_connection_failed"
2. 封装Requests调用工具函数
把所有第三方API调用统一放到工具函数里,集中捕获Requests异常并转换为自定义DRF异常:
import requests from .exceptions import ( ThirdPartyTimeoutError, ThirdPartyConnectionError, ThirdPartyAPIError ) def call_third_party_api(url, method="GET", **kwargs): try: response = requests.request(method, url, **kwargs) # 处理第三方返回的非2xx状态码 response.raise_for_status() return response.json() except requests.exceptions.Timeout: raise ThirdPartyTimeoutError() except requests.exceptions.ConnectionError: raise ThirdPartyConnectionError() except requests.exceptions.HTTPError as e: detail = f"第三方服务返回错误: {str(e)}" raise ThirdPartyAPIError(detail=detail) except requests.exceptions.RequestException as e: # 兜底处理其他所有Requests异常 raise ThirdPartyAPIError(detail=f"第三方请求失败: {str(e)}")
3. 在APIView中使用工具函数
视图里直接调用工具函数即可,DRF会自动处理自定义的APIException子类,返回标准DRF错误响应:
from rest_framework.views import APIView from rest_framework.response import Response from .utils import call_third_party_api class MyThirdPartyView(APIView): def get(self, request): data = call_third_party_api("https://third-party-api.com/data") return Response(data)
4. 额外优化建议
- 异常分级处理:根据业务需求给不同第三方异常分配不同
status_code,比如连接错误返回503,第三方返回400则同步返回400给前端 - 日志记录:捕获异常时详细记录请求URL、参数、异常信息,方便后续排查问题
- 重试机制:对超时、连接错误这类临时异常,可结合
tenacity库实现自动重试后再抛出异常 - 全局异常处理:若需统一异常响应格式,可通过DRF的
EXCEPTION_HANDLER自定义全局处理逻辑
内容的提问来源于stack exchange,提问作者Darío Fragas
相关产品推荐
相关产品推荐

