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
53 changes: 30 additions & 23 deletions Lib/logging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1127,29 +1127,36 @@ def emit(self, record):
msg['Subject'] = self.getSubject(record)
msg['Date'] = email.utils.localtime()
msg.set_content(self.format(record))
if self.username:
if self.secure is not None:
import ssl

try:
keyfile = self.secure[0]
except IndexError:
keyfile = None

try:
certfile = self.secure[1]
except IndexError:
certfile = None

context = ssl._create_stdlib_context(
certfile=certfile, keyfile=keyfile
)
smtp.ehlo()
smtp.starttls(context=context)
smtp.ehlo()
smtp.login(self.username, self.password)
smtp.send_message(msg)
smtp.quit()
try:

@picnixz picnixz Aug 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't put it in an entire try-catch. Only the relevant parts.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address this. Don't use a full try-except block around code that doesn't need it.

if self.username:
if self.secure is not None:
import ssl

try:
keyfile = self.secure[0]
except IndexError:
keyfile = None

try:
certfile = self.secure[1]
except IndexError:
certfile = None

context = ssl._create_stdlib_context(
certfile=certfile, keyfile=keyfile
)
smtp.ehlo()
smtp.starttls(context=context)
smtp.ehlo()
smtp.login(self.username, self.password)
smtp.send_message(msg)
smtp.quit()
except Exception:
try:
smtp.close()
except Exception:
pass
raise
Comment on lines +1154 to +1159

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only put a try-except when smtp is actually being used.

except Exception:
self.handleError(record)

Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,25 @@ def test_basic(self):
self.assertEndsWith(data, '\n\nHello \u2713')
h.close()

def test_connection_closed_on_send_failure(self):
handler = logging.handlers.SMTPHandler(
("localhost", 25),
"me@example.com",
"you@example.com",
"subject",
timeout=self.TIMEOUT,
)
record = logging.makeLogRecord({"msg": "hello"})

smtp = unittest.mock.Mock()
smtp.send_message.side_effect = OSError("send failed")

with unittest.mock.patch("smtplib.SMTP", return_value=smtp):
with support.captured_stderr():
handler.emit(record)

smtp.close.assert_called_once()

def process_message(self, *args):
self.messages.append(args)
self.handled.set()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:mod:`logging`: ensure that :class:`logging.handlesr.SMTPHandler`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:mod:`logging`: ensure that :class:`logging.handlesr.SMTPHandler`
:mod:`logging`: ensure that :class:`logging.handlers.SMTPHandler`

Sorry there was a typo in my suggestion.

correctly releases resources on SMTP connection failures.
Loading