try/except无法捕获Future的TimeoutError且异常为空,求技术解答
问题分析与解决
你的问题核心在于**两个同名但不同类的TimeoutError**在“搞混淆”,导致异常捕获逻辑完全没按预期工作,具体拆解和解决方法如下:
为什么try/except TimeoutError抓不到异常?
你代码里except TimeoutError:捕获的是Python内置的builtins.TimeoutError,但concurrent.futures.Future.result()抛出的是**concurrent.futures.TimeoutError**——这俩名字完全一样,但属于不同模块的独立类,Python会把它们当成完全不同的异常类型,所以你的捕获语句根本匹配不上。
你可以在代码里加两行验证一下:
import concurrent.futures import builtins print(builtins.TimeoutError) # 输出:<class 'TimeoutError'> print(concurrent.futures.TimeoutError) # 输出:<class 'concurrent.futures._base.TimeoutError'>
为什么except Exception捕获后str(e)为空?
看你贴的concurrent.futures._base.py代码,它抛出异常时是raise TimeoutError(),没有传入任何错误消息参数。这类无参数构造的异常实例,其__str__()方法返回的是空字符串,所以你用str(e)输出时就会看到空内容。
解决方法
方法1:明确捕获concurrent.futures.TimeoutError
直接导入这个正确的异常类,针对性捕获:
import asyncio from concurrent.futures import TimeoutError # 导入concurrent模块的TimeoutError def your_function(loop): future = asyncio.run_coroutine_threadsafe(do_stuff(), loop=loop) try: return future.result(timeout=3) except TimeoutError: raise TimeoutError("Time out occurred while doing stuff")
方法2:兼容两种TimeoutError类型
如果你的代码场景中可能同时抛出内置和concurrent的TimeoutError,可以同时捕获:
import asyncio import builtins from concurrent.futures import TimeoutError as FuturesTimeoutError def your_function(loop): future = asyncio.run_coroutine_threadsafe(do_stuff(), loop=loop) try: return future.result(timeout=3) except (builtins.TimeoutError, FuturesTimeoutError): raise builtins.TimeoutError("Time out occurred while doing stuff")
补充优化:避免空异常消息
如果希望自定义异常的信息更清晰,也可以考虑自定义异常类,或者在抛出时确保消息被正确传递,彻底避免空字符串的问题。
内容的提问来源于stack exchange,提问作者Jakub Czaplicki
相关产品推荐
相关产品推荐

