209 lines
8.3 KiB
Python
209 lines
8.3 KiB
Python
import eventlet
|
||
import logging
|
||
|
||
# 配置 eventlet 日志,抑制 IOClosed 等错误日志
|
||
logging.getLogger('eventlet.hubs').setLevel(logging.CRITICAL)
|
||
logging.getLogger('eventlet.greenio').setLevel(logging.CRITICAL)
|
||
|
||
# 进行猴子补丁操作
|
||
eventlet.monkey_patch()
|
||
|
||
# 配置 eventlet hub 以更优雅地处理所有错误
|
||
try:
|
||
from eventlet.hubs import hub
|
||
from eventlet import hubs
|
||
import traceback
|
||
|
||
# 保存原始的方法
|
||
original_handle_error = hub.Hub.handle_error
|
||
original_switch = hubs.hub.Hub.switch
|
||
original_fire_timers = hubs.hub.Hub.fire_timers
|
||
original_trampoline = hubs.trampoline
|
||
|
||
def custom_handle_error(self, context, type, value, tb):
|
||
# 捕获并打印所有 eventlet.hubs 相关错误,不再往外raise
|
||
print(f"[Eventlet Hub Error] Type: {type.__name__}, Value: {value}")
|
||
print(f"[Context] {context}")
|
||
print("[Traceback]")
|
||
traceback.print_tb(tb)
|
||
# 不再调用原始方法,直接返回,不往外传播错误
|
||
|
||
def custom_switch(self):
|
||
try:
|
||
return original_switch(self)
|
||
except Exception as e:
|
||
# 捕获 switch 方法中所有异常
|
||
print(f"[Eventlet Switch Error] {type(e).__name__}: {e}")
|
||
print("[Traceback]")
|
||
traceback.print_exc()
|
||
# 返回 None 继续运行,不往外传播错误
|
||
return None
|
||
|
||
def custom_fire_timers(self):
|
||
try:
|
||
return original_fire_timers(self)
|
||
except Exception as e:
|
||
# 捕获 fire_timers 方法中所有异常
|
||
print(f"[Eventlet Fire Timers Error] {type(e).__name__}: {e}")
|
||
print("[Traceback]")
|
||
traceback.print_exc()
|
||
# 返回继续运行,不往外传播错误
|
||
return
|
||
|
||
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
|
||
|
||
# 替换原始方法
|
||
hub.Hub.handle_error = custom_handle_error
|
||
hubs.hub.Hub.switch = custom_switch
|
||
hubs.hub.Hub.fire_timers = custom_fire_timers
|
||
hubs.trampoline = custom_trampoline
|
||
|
||
# 同样处理 greenio 模块的所有相关方法,捕获所有异常
|
||
from eventlet import greenio
|
||
|
||
# 保存原始的 greenio 方法
|
||
original_recv_loop = greenio.base.GreenSocket._recv_loop
|
||
original_recv_into = greenio.base.GreenSocket.recv_into
|
||
original_send_loop = greenio.base.GreenSocket._send_loop
|
||
original_send = greenio.base.GreenSocket.send
|
||
|
||
def safe_io_operation(io_func, *args, **kwargs):
|
||
"""安全执行 IO 操作,捕获所有异常"""
|
||
try:
|
||
return io_func(*args, **kwargs)
|
||
except Exception as e:
|
||
# 捕获所有 IO 操作异常
|
||
print(f"[Eventlet IO Error] {io_func.__name__}: {type(e).__name__}: {e}")
|
||
print("[Traceback]")
|
||
traceback.print_exc()
|
||
# 根据操作类型返回适当的默认值
|
||
if 'recv' in io_func.__name__ or 'read' in io_func.__name__:
|
||
return b'' if 'recv' in io_func.__name__ else ''
|
||
elif 'send' in io_func.__name__ or 'write' in io_func.__name__:
|
||
return 0
|
||
return None
|
||
|
||
def custom_recv_loop(self, recv_func, recv_args, *args, **kwargs):
|
||
return safe_io_operation(original_recv_loop, self, recv_func, recv_args, *args, **kwargs)
|
||
|
||
def custom_recv_into(self, buffer, nbytes=0, flags=0):
|
||
return safe_io_operation(original_recv_into, self, buffer, nbytes, flags)
|
||
|
||
def custom_send_loop(self, send_func, data, *args, **kwargs):
|
||
return safe_io_operation(original_send_loop, self, send_func, data, *args, **kwargs)
|
||
|
||
def custom_send(self, data, flags=0):
|
||
return safe_io_operation(original_send, self, data, flags)
|
||
|
||
# 替换 greenio 方法
|
||
greenio.base.GreenSocket._recv_loop = custom_recv_loop
|
||
greenio.base.GreenSocket.recv_into = custom_recv_into
|
||
greenio.base.GreenSocket._send_loop = custom_send_loop
|
||
greenio.base.GreenSocket.send = custom_send
|
||
|
||
# 处理 WSGI 中的所有错误
|
||
try:
|
||
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):
|
||
try:
|
||
return original_wsgi_handle_one_request(self)
|
||
except Exception as e:
|
||
# 捕获 WSGI 请求处理中的所有异常
|
||
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):
|
||
try:
|
||
return original_wsgi_handle_one_response(self)
|
||
except Exception as e:
|
||
# 捕获 WSGI 响应处理中的所有异常
|
||
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
|
||
except Exception as e:
|
||
# 如果修改失败,忽略错误
|
||
print(f"[WSGI Patch Error] {e}")
|
||
|
||
# 修改 eventlet 所有可能抛出异常的核心方法
|
||
# 遍历 hub.Hub 类的所有方法,包装可能抛出异常的方法
|
||
for method_name in dir(hub.Hub):
|
||
if not method_name.startswith('_'):
|
||
method = getattr(hub.Hub, method_name)
|
||
if callable(method):
|
||
def wrap_method(original_method):
|
||
def wrapped_method(self, *args, **kwargs):
|
||
try:
|
||
return original_method(self, *args, **kwargs)
|
||
except Exception as e:
|
||
print(f"[Eventlet Hub Method Error] {method_name}: {type(e).__name__}: {e}")
|
||
print("[Traceback]")
|
||
traceback.print_exc()
|
||
# 返回适当的默认值
|
||
if method_name == 'add':
|
||
return None
|
||
elif method_name == 'remove':
|
||
return None
|
||
return None
|
||
return wrapped_method
|
||
|
||
# 替换原始方法
|
||
setattr(hub.Hub, method_name, wrap_method(method))
|
||
|
||
print("[Eventlet Error Handling] All eventlet.hubs errors will be caught and printed, not raised")
|
||
except Exception as e:
|
||
# 如果修改失败,打印错误但继续运行
|
||
print(f"[Eventlet Patch Initialization Error] {e}")
|
||
traceback.print_exc()
|
||
|
||
from flask import Flask
|
||
from .views.routes import main_bp
|
||
from .views.file import file_bp
|
||
from .config import Config
|
||
from .extensions import init_extensions,register_namespaces
|
||
|
||
def create_app():
|
||
app = Flask(__name__, template_folder="../templates", static_folder="../static",static_url_path="/vsc-like/static")
|
||
app.config.from_object(Config)
|
||
@app.route('/')
|
||
def hello():
|
||
return 'Hello, World!'
|
||
|
||
# 注册蓝图
|
||
app.register_blueprint(main_bp)
|
||
app.register_blueprint(file_bp)
|
||
# 初始化SocketIO
|
||
init_extensions(app)
|
||
|
||
register_namespaces(app)
|
||
|
||
return app
|