https://github.com/python/cpython/commit/d66501379c864b662c2b3eea7c036aa4f3647661
commit: d66501379c864b662c2b3eea7c036aa4f3647661
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-10-10T12:41:56+03:00
summary:

[3.15] gh-135683: Honor raiseExceptions when opening the file fails in 
FileHandler (GH-154542) (GH-157807)

FileHandler and WatchedFileHandler opened the file outside the try block
that reports errors via handleError(), so an error while opening the file
was raised instead of being handled, ignoring raiseExceptions.
(cherry picked from commit e8ac9c4369b383d38806245bf5789689af1e19cd)

Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Vinay Sajip <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst
M Lib/logging/__init__.py
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 80ce896a78004ee..f6248e9f88a5b6d 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -1263,7 +1263,12 @@ def emit(self, record):
         """
         if self.stream is None:
             if self.mode != 'w' or not self._closed:
-                self.stream = self._open()
+                # Report an error while opening the file, like emit errors.
+                try:
+                    self.stream = self._open()
+                except Exception:
+                    self.handleError(record)
+                    return
         if self.stream:
             StreamHandler.emit(self, record)
 
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 8866b1639fbd00a..054b456a3cc5947 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -540,8 +540,13 @@ def emit(self, record):
         If underlying file has changed, reopen the file before emitting the
         record to it.
         """
-        self.reopenIfNeeded()
-        logging.FileHandler.emit(self, record)
+        # Report an error while reopening the file, like emit errors.
+        try:
+            self.reopenIfNeeded()
+        except Exception:
+            self.handleError(record)
+        else:
+            logging.FileHandler.emit(self, record)
 
 
 class SocketHandler(logging.Handler):
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index ff4367c34e18891..1b20e32367a0807 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -6415,6 +6415,46 @@ def test_emit_after_closing_in_write_mode(self):
         with open(self.fn) as fp:
             self.assertEqual(fp.read().strip(), '1')
 
+    def _check_open_error(self, h):
+        # gh-135683: an error while opening the file in emit() respects
+        # raiseExceptions, like an error during the actual write.
+        r = logging.makeLogRecord({})
+        old_raise = logging.raiseExceptions
+        self.addCleanup(setattr, logging, 'raiseExceptions', old_raise)
+
+        logging.raiseExceptions = True
+        with support.captured_stderr() as stderr:
+            h.handle(r)
+        self.assertIn('\nFileNotFoundError:', stderr.getvalue())
+
+        logging.raiseExceptions = False
+        with support.captured_stderr() as stderr:
+            h.handle(r)
+        self.assertEqual('', stderr.getvalue())
+
+    def test_emit_open_error(self):
+        # FileHandler with delay: the failing open happens in emit().
+        d = tempfile.mkdtemp()
+        self.addCleanup(os_helper.rmtree, d)
+        h = logging.FileHandler(os.path.join(d, 'missing', 'a.log'),
+                                encoding='utf-8', delay=True)
+        self.addCleanup(h.close)
+        self._check_open_error(h)
+
+    @unittest.skipIf(os.name == 'nt',
+                     'WatchedFileHandler not appropriate for Windows.')
+    def test_emit_reopen_error(self):
+        # WatchedFileHandler: reopenIfNeeded() fails after the dir is removed.
+        d = tempfile.mkdtemp()
+        self.addCleanup(os_helper.rmtree, d)
+        subdir = os.path.join(d, 'sub')
+        os.mkdir(subdir)
+        h = logging.handlers.WatchedFileHandler(
+            os.path.join(subdir, 'b.log'), encoding='utf-8')
+        self.addCleanup(h.close)
+        os_helper.rmtree(subdir)
+        self._check_open_error(h)
+
 class RotatingFileHandlerTest(BaseFileTest):
     def test_should_not_rollover(self):
         # If file is empty rollover never occurs
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst 
b/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst
new file mode 100644
index 000000000000000..532ae22d017a565
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst
@@ -0,0 +1,3 @@
+:class:`logging.FileHandler` and :class:`logging.handlers.WatchedFileHandler`
+now honor :data:`logging.raiseExceptions` for errors that occur while opening
+the file, like for other errors during logging.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to