Skip to content

Commit e8ac9c4

Browse files
serhiy-storchakavsajipclaude
authored
gh-135683: Honor raiseExceptions when opening the file fails in FileHandler (GH-154542)
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. Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5bbf4fa commit e8ac9c4

4 files changed

Lines changed: 56 additions & 3 deletions

File tree

‎Lib/logging/__init__.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,12 @@ def emit(self, record):
12631263
"""
12641264
if self.stream is None:
12651265
if self.mode != 'w' or not self._closed:
1266-
self.stream = self._open()
1266+
# Report an error while opening the file, like emit errors.
1267+
try:
1268+
self.stream = self._open()
1269+
except Exception:
1270+
self.handleError(record)
1271+
return
12671272
if self.stream:
12681273
StreamHandler.emit(self, record)
12691274

‎Lib/logging/handlers.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,8 +563,13 @@ def emit(self, record):
563563
If underlying file has changed, reopen the file before emitting the
564564
record to it.
565565
"""
566-
self.reopenIfNeeded()
567-
logging.FileHandler.emit(self, record)
566+
# Report an error while reopening the file, like emit errors.
567+
try:
568+
self.reopenIfNeeded()
569+
except Exception:
570+
self.handleError(record)
571+
else:
572+
logging.FileHandler.emit(self, record)
568573

569574

570575
class SocketHandler(logging.Handler):

‎Lib/test/test_logging.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6503,6 +6503,46 @@ def test_emit_after_closing_in_write_mode(self):
65036503
with open(self.fn) as fp:
65046504
self.assertEqual(fp.read().strip(), '1')
65056505

6506+
def _check_open_error(self, h):
6507+
# gh-135683: an error while opening the file in emit() respects
6508+
# raiseExceptions, like an error during the actual write.
6509+
r = logging.makeLogRecord({})
6510+
old_raise = logging.raiseExceptions
6511+
self.addCleanup(setattr, logging, 'raiseExceptions', old_raise)
6512+
6513+
logging.raiseExceptions = True
6514+
with support.captured_stderr() as stderr:
6515+
h.handle(r)
6516+
self.assertIn('\nFileNotFoundError:', stderr.getvalue())
6517+
6518+
logging.raiseExceptions = False
6519+
with support.captured_stderr() as stderr:
6520+
h.handle(r)
6521+
self.assertEqual('', stderr.getvalue())
6522+
6523+
def test_emit_open_error(self):
6524+
# FileHandler with delay: the failing open happens in emit().
6525+
d = tempfile.mkdtemp()
6526+
self.addCleanup(os_helper.rmtree, d)
6527+
h = logging.FileHandler(os.path.join(d, 'missing', 'a.log'),
6528+
encoding='utf-8', delay=True)
6529+
self.addCleanup(h.close)
6530+
self._check_open_error(h)
6531+
6532+
@unittest.skipIf(os.name == 'nt',
6533+
'WatchedFileHandler not appropriate for Windows.')
6534+
def test_emit_reopen_error(self):
6535+
# WatchedFileHandler: reopenIfNeeded() fails after the dir is removed.
6536+
d = tempfile.mkdtemp()
6537+
self.addCleanup(os_helper.rmtree, d)
6538+
subdir = os.path.join(d, 'sub')
6539+
os.mkdir(subdir)
6540+
h = logging.handlers.WatchedFileHandler(
6541+
os.path.join(subdir, 'b.log'), encoding='utf-8')
6542+
self.addCleanup(h.close)
6543+
os_helper.rmtree(subdir)
6544+
self._check_open_error(h)
6545+
65066546
class RotatingFileHandlerTest(BaseFileTest):
65076547
def test_should_not_rollover(self):
65086548
# If file is empty rollover never occurs
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:class:`logging.FileHandler` and :class:`logging.handlers.WatchedFileHandler`
2+
now honor :data:`logging.raiseExceptions` for errors that occur while opening
3+
the file, like for other errors during logging.

0 commit comments

Comments
 (0)