Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Lib/logging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
9 changes: 7 additions & 2 deletions Lib/logging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,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):
Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -6416,6 +6416,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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Loading