使用backoff重试达上限后如何返回API请求状态码?
解决方案
你可以通过在外层封装一个函数的方式,既保留backoff的重试逻辑,又能在重试耗尽后获取并返回错误状态码:
步骤1:保留带backoff装饰的核心调用函数
把原函数改为内部函数(或改名),保持backoff的重试逻辑不变,修正返回类型标注:
import backoff import aiohttp import logging logger = logging.getLogger(__name__) @backoff.on_exception(backoff.expo, aiohttp.ClientResponseError, max_tries=4, logger=logger) async def _call_url(language: str, word: str, headers: dict) -> int: url = f"https://od-api.oxforddictionaries.com:443/api/v2/entries/{language}/{word.lower()}" print(f"Started: {url}") async with aiohttp.ClientSession(headers=headers) as session: async with session.get(url, raise_for_status=True) as response: # 如果不需要响应内容,可移除read()以节省资源 # content = await response.read() status = response.status print("Finished: ", status) return status
步骤2:封装外层函数捕获最终异常
在外层函数中调用核心函数,当backoff耗尽重试次数后,捕获抛出的ClientResponseError并提取状态码返回:
async def call_url(language: str, word: str, headers: dict) -> int: try: return await _call_url(language, word, headers) except aiohttp.ClientResponseError as e: # 重试4次后仍失败,返回异常对应的状态码 return e.status
方案说明
- backoff装饰的是内部函数
_call_url,当它抛出ClientResponseError时,backoff会正常触发重试逻辑,直到达到max_tries=4次。 - 重试耗尽后,内部函数会抛出最后一次的异常,外层函数捕获该异常,从
e.status中获取错误状态码并返回,完全不影响backoff的重试流程。
额外优化建议
- 避免每次调用都创建
ClientSession:可以把session作为参数传入内部函数,或者在外部复用session,减少资源开销。 - 原代码中返回类型标注
-> bytes是错误的,改为-> int更准确,因为返回的是HTTP状态码。
内容的提问来源于stack exchange,提问作者Animeartist
相关产品推荐
相关产品推荐

