diff --git a/code-server-like/app/__init__.py b/code-server-like/app/__init__.py index 19879f5..07f1d8a 100644 --- a/code-server-like/app/__init__.py +++ b/code-server-like/app/__init__.py @@ -11,18 +11,54 @@ eventlet.monkey_patch() # 配置 eventlet hub 以更优雅地处理 IOClosed 错误 try: from eventlet.hubs import hub + from eventlet import hubs + # 保存原始的 handle_error 方法 original_handle_error = hub.Hub.handle_error + original_switch = hubs.hub.Hub.switch def custom_handle_error(self, context, type, value, tb): - # 忽略 IOClosed 错误 - if type.__name__ == 'IOClosed' and 'Operation on closed file' in str(value): + # 忽略 IOClosed 错误和相关的 EOFError + error_str = str(value) + if (type.__name__ == 'IOClosed' and 'Operation on closed file' in error_str) or \ + (type.__name__ == 'EOFError') or \ + (type.__name__ == 'OSError' and 'Bad file descriptor' in error_str): return # 其他错误调用原始方法 original_handle_error(self, context, type, value, tb) + def custom_switch(self): + try: + return original_switch(self) + except Exception as e: + # 捕获 switch 方法中可能出现的 IOClosed 错误 + error_str = str(e) + if (type(e).__name__ == 'IOClosed' and 'Operation on closed file' in error_str) or \ + (type(e).__name__ == 'EOFError') or \ + (type(e).__name__ == 'OSError' and 'Bad file descriptor' in error_str): + # 优雅处理,返回继续运行 + return None + # 其他异常重新抛出 + raise + # 替换原始方法 hub.Hub.handle_error = custom_handle_error + hubs.hub.Hub.switch = custom_switch + + # 同样处理 greenio 模块的错误 + from eventlet import greenio + original_recv_loop = greenio.base.GreenSocket._recv_loop + + def custom_recv_loop(self, recv_func, recv_args, *args, **kwargs): + try: + return original_recv_loop(self, recv_func, recv_args, *args, **kwargs) + except (hubs.IOClosed, EOFError, OSError) as e: + # 优雅处理 IO 错误 + if hasattr(e, 'errno') and e.errno in (9, 107): # Bad file descriptor or Operation on closed file + return b'' + raise + + greenio.base.GreenSocket._recv_loop = custom_recv_loop except Exception as e: # 如果修改失败,忽略错误 pass diff --git a/code-server-like/run.py b/code-server-like/run.py index c7e4dda..2d50248 100644 --- a/code-server-like/run.py +++ b/code-server-like/run.py @@ -10,23 +10,11 @@ logging.getLogger('werkzeug').setLevel(logging.ERROR) app = create_app() if __name__ == '__main__': - try: - socketio.run( - app, - host="0.0.0.0", - port=5200, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - log_output=False # 禁用详细输出 - ) - except KeyboardInterrupt: - print("Server stopped by user") - except Exception as e: - # 捕获所有异常,包括 eventlet 内部的 IOClosed 错误 - if "IOClosed" in str(type(e).__name__) or "Operation on closed file" in str(e): - # 优雅处理 eventlet 关闭文件的错误 - print("Eventlet IOClosed error handled gracefully") - else: - # 其他异常仍然打印 - import traceback - traceback.print_exc() + socketio.run( + app, + host="0.0.0.0", + port=5200, + debug=False, # 开发期打开 + allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 + log_output=False # 禁用详细输出 + )