fix: lower timeout when validating Email Account (#37147)

* fix: reduce Email Domain validate timeout

* fix: lower timeout when validating Email Account (SMTP)

* fix: lower timeout when validating Email Account (IMAP/POP)
This commit is contained in:
s-aga-r 2026-02-19 12:01:28 +05:30 committed by GitHub
parent 8fc4c52f03
commit e735ae774e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 10 deletions

View file

@ -179,6 +179,7 @@ class EmailAccount(Document):
):
if validate_oauth or self.password or self.smtp_server in ("127.0.0.1", "localhost"):
if self.enable_incoming:
self.flags.validate_imap_pop_connection = True
self.get_incoming_server()
self.no_failed = 0
@ -212,8 +213,9 @@ class EmailAccount(Document):
if not self.smtp_server:
frappe.throw(_("SMTP Server is required"))
server = self.get_smtp_server()
return server.session
self.flags.validate_smtp_connection = True
self.get_smtp_server().session
del self._smtp_server_instance
def before_save(self):
messages = []
@ -304,6 +306,9 @@ class EmailAccount(Document):
if not args.get("host"):
frappe.throw(_("{0} is required").format("Email Server"))
if self.flags.validate_imap_pop_connection:
args.timeout = 15
email_server = EmailServer(frappe._dict(args))
self.check_email_server_connection(email_server, in_receive)
@ -507,7 +512,7 @@ class EmailAccount(Document):
return oauth_token.get_password("access_token") if oauth_token else None
def sendmail_config(self):
return {
config = {
"email_account": self.name,
"server": self.smtp_server,
"port": cint(self.smtp_port),
@ -519,6 +524,11 @@ class EmailAccount(Document):
"access_token": self.get_access_token(),
}
if self.flags.validate_smtp_connection:
config["timeout"] = 15
return config
def get_smtp_server(self):
"""Get SMTPServer (wrapper around actual smtplib object) for this account.

View file

@ -111,7 +111,7 @@ class EmailDomain(Document):
conn_method = poplib.POP3_SSL if self.use_ssl else poplib.POP3
self.use_starttls = cint(self.use_imap and self.use_starttls and not self.use_ssl)
incoming_conn = conn_method(self.email_server, port=self.incoming_port, timeout=30)
incoming_conn = conn_method(self.email_server, port=self.incoming_port, timeout=15)
incoming_conn.logout() if self.use_imap else incoming_conn.quit()
@handle_error("outgoing")
@ -124,4 +124,4 @@ class EmailDomain(Document):
elif self.use_tls:
self.smtp_port = self.smtp_port or 587
conn_method((self.smtp_server or ""), cint(self.smtp_port), timeout=30).quit()
conn_method((self.smtp_server or ""), cint(self.smtp_port), timeout=15).quit()

View file

@ -69,7 +69,10 @@ class EmailServer:
def __init__(self, args=None):
self.retry_limit = 3
self.retry_count = 0
self.settings = args or frappe._dict()
self.pop_timeout = self.settings.timeout or frappe.conf.pop_timeout
self.imap_timeout = self.settings.timeout or frappe.conf.imap_timeout
def connect(self):
"""Connect to **Email Account**."""
@ -82,12 +85,12 @@ class EmailServer:
self.imap = imaplib.IMAP4_SSL(
self.settings.host,
self.settings.incoming_port,
timeout=frappe.conf.pop_timeout,
timeout=self.imap_timeout,
ssl_context=ssl.create_default_context(),
)
else:
self.imap = imaplib.IMAP4(
self.settings.host, self.settings.incoming_port, timeout=frappe.conf.pop_timeout
self.settings.host, self.settings.incoming_port, timeout=self.imap_timeout
)
if cint(self.settings.use_starttls):
@ -119,12 +122,12 @@ class EmailServer:
self.pop = poplib.POP3_SSL(
self.settings.host,
self.settings.incoming_port,
timeout=frappe.conf.pop_timeout,
timeout=self.pop_timeout,
context=ssl.create_default_context(),
)
else:
self.pop = poplib.POP3(
self.settings.host, self.settings.incoming_port, timeout=frappe.conf.pop_timeout
self.settings.host, self.settings.incoming_port, timeout=self.pop_timeout
)
if self.settings.use_oauth:

View file

@ -26,6 +26,7 @@ class SMTPServer:
use_ssl=None,
use_oauth=0,
access_token=None,
timeout=2 * 60,
):
self.login = login
self.email_account = email_account
@ -37,6 +38,7 @@ class SMTPServer:
self.use_oauth = use_oauth
self.access_token = access_token
self._session = None
self.timeout = timeout
if not self.server:
frappe.msgprint(
@ -72,7 +74,7 @@ class SMTPServer:
SMTP = smtplib.SMTP_SSL if self.use_ssl else smtplib.SMTP
try:
_session = SMTP(self.server, self.port, timeout=2 * 60)
_session = SMTP(self.server, self.port, timeout=self.timeout)
if not _session:
frappe.msgprint(
_("Could not connect to outgoing email server"), raise_exception=frappe.OutgoingEmailError