From 8f49e3cd2aa5027ff98cc20d408851640edd587f Mon Sep 17 00:00:00 2001 From: YUHAO-corn Date: Sat, 16 May 2026 22:55:05 +0800 Subject: [PATCH] fix: guard log flush against OSError --- app/logger.py | 5 ++++- tests-unit/app_test/logger_test.py | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests-unit/app_test/logger_test.py diff --git a/app/logger.py b/app/logger.py index bde815822..8c288aab5 100644 --- a/app/logger.py +++ b/app/logger.py @@ -66,7 +66,10 @@ class LogInterceptor(io.TextIOWrapper): super().write(data) def flush(self): - super().flush() + try: + super().flush() + except OSError: + pass for cb in self._flush_callbacks: cb(self._logs_since_flush) self._logs_since_flush = [] diff --git a/tests-unit/app_test/logger_test.py b/tests-unit/app_test/logger_test.py new file mode 100644 index 000000000..614777e9f --- /dev/null +++ b/tests-unit/app_test/logger_test.py @@ -0,0 +1,26 @@ +import io + +from app.logger import LogInterceptor + + +class FlushErrorBuffer(io.BytesIO): + def flush(self): + raise OSError(22, "Invalid argument") + + +class FlushErrorStream: + buffer = FlushErrorBuffer() + encoding = "utf-8" + line_buffering = False + + +def test_log_interceptor_flush_ignores_oserror_and_runs_callbacks(): + interceptor = LogInterceptor(FlushErrorStream()) + interceptor._logs_since_flush = [{"m": "message"}] + flushed_logs = [] + + interceptor.on_flush(lambda logs: flushed_logs.append(list(logs))) + interceptor.flush() + + assert flushed_logs == [[{"m": "message"}]] + assert interceptor._logs_since_flush == []