Files
hsa/code-server-like/app/__init__.py

209 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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