fix module 'eventlet.hubs' has no attribute 'handle_error'

This commit is contained in:
CakeCN
2026-01-07 23:57:25 +08:00
parent f8e0b461ba
commit 4dd2667785

View File

@@ -14,123 +14,142 @@ try:
import eventlet import eventlet
import traceback import traceback
# 获取当前的 hub 实例 # 只修改存在的属性,避免引用错误
current_hub = hubs.get_hub() if hasattr(hubs, 'trampoline'):
# 保存原始的trampoline方法
original_trampoline = hubs.trampoline
# 保存原始的方法 def custom_trampoline(fd, read=False, write=False, timeout=None, timeout_exc=None):
original_handle_error = hubs.handle_error try:
original_trampoline = hubs.trampoline return original_trampoline(fd, read, write, timeout, timeout_exc)
except Exception as e:
# 捕获 trampoline 方法中所有异常
print(f"[Eventlet Trampoline Error] {type(e).__name__}: {e}")
print(f"[Params] fd: {fd}, read: {read}, write: {write}, timeout: {timeout}")
print("[Traceback]")
traceback.print_exc()
# 返回 None 继续运行,不往外传播错误
return None
def custom_handle_error(context, type, value, tb): # 替换原始方法
# 捕获并打印所有 eventlet.hubs 相关错误不再往外raise hubs.trampoline = custom_trampoline
print(f"[Eventlet Hub Error] Type: {type.__name__}, Value: {value}")
print(f"[Context] {context}")
print("[Traceback]")
traceback.print_tb(tb)
# 不再调用原始方法,直接返回,不往外传播错误
def custom_trampoline(fd, read=False, write=False, timeout=None, timeout_exc=None):
try:
return original_trampoline(fd, read, write, timeout, timeout_exc)
except Exception as e:
# 捕获 trampoline 方法中所有异常
print(f"[Eventlet Trampoline Error] {type(e).__name__}: {e}")
print(f"[Params] fd: {fd}, read: {read}, write: {write}, timeout: {timeout}")
print("[Traceback]")
traceback.print_exc()
# 返回 None 继续运行,不往外传播错误
return None
# 替换原始方法
hubs.handle_error = custom_handle_error
hubs.trampoline = custom_trampoline
# 同样处理 greenio 模块的所有相关方法,捕获所有异常 # 同样处理 greenio 模块的所有相关方法,捕获所有异常
from eventlet import greenio from eventlet import greenio
# 保存原始的 greenio 方法 # 保存并替换原始的 greenio 方法(只修改存在的方法)
original_recv_loop = greenio.base.GreenSocket._recv_loop if hasattr(greenio.base.GreenSocket, '_recv_loop'):
original_recv_into = greenio.base.GreenSocket.recv_into original_recv_loop = greenio.base.GreenSocket._recv_loop
original_send_loop = greenio.base.GreenSocket._send_loop
original_send = greenio.base.GreenSocket.send
def safe_io_operation(io_func, *args, **kwargs): def custom_recv_loop(self, recv_func, recv_args, *args, **kwargs):
"""安全执行 IO 操作,捕获所有异常""" try:
try: return original_recv_loop(self, recv_func, recv_args, *args, **kwargs)
return io_func(*args, **kwargs) except Exception as e:
except Exception as e: # 捕获所有 IO 操作异常
# 捕获所有 IO 操作异常 print(f"[Eventlet IO Error] _recv_loop: {type(e).__name__}: {e}")
print(f"[Eventlet IO Error] {io_func.__name__}: {type(e).__name__}: {e}") print("[Traceback]")
print("[Traceback]") traceback.print_exc()
traceback.print_exc() # 返回空字节串继续运行
# 根据操作类型返回适当的默认值 return b''
if 'recv' in io_func.__name__ or 'read' in io_func.__name__:
return b'' if 'recv' in io_func.__name__ else '' greenio.base.GreenSocket._recv_loop = custom_recv_loop
elif 'send' in io_func.__name__ or 'write' in io_func.__name__:
if hasattr(greenio.base.GreenSocket, 'recv_into'):
original_recv_into = greenio.base.GreenSocket.recv_into
def custom_recv_into(self, buffer, nbytes=0, flags=0):
try:
return original_recv_into(self, buffer, nbytes, flags)
except Exception as e:
# 捕获所有 IO 操作异常
print(f"[Eventlet IO Error] recv_into: {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 返回 0 继续运行
return 0 return 0
return None
def custom_recv_loop(self, recv_func, recv_args, *args, **kwargs): greenio.base.GreenSocket.recv_into = custom_recv_into
return safe_io_operation(original_recv_loop, self, recv_func, recv_args, *args, **kwargs)
def custom_recv_into(self, buffer, nbytes=0, flags=0): if hasattr(greenio.base.GreenSocket, '_send_loop'):
return safe_io_operation(original_recv_into, self, buffer, nbytes, flags) original_send_loop = greenio.base.GreenSocket._send_loop
def custom_send_loop(self, send_func, data, *args, **kwargs): def custom_send_loop(self, send_func, data, *args, **kwargs):
return safe_io_operation(original_send_loop, self, send_func, data, *args, **kwargs) try:
return original_send_loop(self, send_func, data, *args, **kwargs)
except Exception as e:
# 捕获所有 IO 操作异常
print(f"[Eventlet IO Error] _send_loop: {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 返回 0 继续运行
return 0
def custom_send(self, data, flags=0): greenio.base.GreenSocket._send_loop = custom_send_loop
return safe_io_operation(original_send, self, data, flags)
# 替换 greenio 方法 if hasattr(greenio.base.GreenSocket, 'send'):
greenio.base.GreenSocket._recv_loop = custom_recv_loop original_send = greenio.base.GreenSocket.send
greenio.base.GreenSocket.recv_into = custom_recv_into
greenio.base.GreenSocket._send_loop = custom_send_loop def custom_send(self, data, flags=0):
greenio.base.GreenSocket.send = custom_send try:
return original_send(self, data, flags)
except Exception as e:
# 捕获所有 IO 操作异常
print(f"[Eventlet IO Error] send: {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 返回 0 继续运行
return 0
greenio.base.GreenSocket.send = custom_send
# 处理 WSGI 中的所有错误 # 处理 WSGI 中的所有错误
try: try:
import eventlet.wsgi import eventlet.wsgi
original_wsgi_handle_one_request = eventlet.wsgi.HttpProtocol.handle_one_request
original_wsgi_handle_one_response = eventlet.wsgi.HttpProtocol.handle_one_response
def custom_wsgi_handle_one_request(self): if hasattr(eventlet.wsgi.HttpProtocol, 'handle_one_request'):
try: original_wsgi_handle_one_request = eventlet.wsgi.HttpProtocol.handle_one_request
return original_wsgi_handle_one_request(self)
except Exception as e: def custom_wsgi_handle_one_request(self):
# 捕获 WSGI 请求处理中的所有异常
print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 清理连接状态并返回,不往外传播错误
try: try:
self.finish() return original_wsgi_handle_one_request(self)
except Exception: except Exception as e:
pass # 捕获 WSGI 请求处理中的所有异常
return print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 清理连接状态并返回,不往外传播错误
try:
self.finish()
except Exception:
pass
return
def custom_wsgi_handle_one_response(self): eventlet.wsgi.HttpProtocol.handle_one_request = custom_wsgi_handle_one_request
try:
return original_wsgi_handle_one_response(self) if hasattr(eventlet.wsgi.HttpProtocol, 'handle_one_response'):
except Exception as e: original_wsgi_handle_one_response = eventlet.wsgi.HttpProtocol.handle_one_response
# 捕获 WSGI 响应处理中的所有异常
print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}") def custom_wsgi_handle_one_response(self):
print("[Traceback]")
traceback.print_exc()
# 清理连接状态并返回,不往外传播错误
try: try:
self.finish() return original_wsgi_handle_one_response(self)
except Exception: except Exception as e:
pass # 捕获 WSGI 响应处理中的所有异常
return print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}")
print("[Traceback]")
traceback.print_exc()
# 清理连接状态并返回,不往外传播错误
try:
self.finish()
except Exception:
pass
return
eventlet.wsgi.HttpProtocol.handle_one_request = custom_wsgi_handle_one_request eventlet.wsgi.HttpProtocol.handle_one_response = custom_wsgi_handle_one_response
eventlet.wsgi.HttpProtocol.handle_one_response = custom_wsgi_handle_one_response
except Exception as e: except Exception as e:
# 如果修改失败,忽略错误 # 如果修改失败,忽略错误
print(f"[WSGI Patch Error] {e}") print(f"[WSGI Patch Error] {e}")
print("[Eventlet Error Handling] All eventlet.hubs errors will be caught and printed, not raised") print("[Eventlet Error Handling] Eventlet errors will be caught and printed, not raised")
except Exception as e: except Exception as e:
# 如果修改失败,打印错误但继续运行 # 如果修改失败,打印错误但继续运行
print(f"[Eventlet Patch Initialization Error] {e}") print(f"[Eventlet Patch Initialization Error] {e}")