diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 14a3cfd9f1..59c2d5bba8 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -148,7 +148,7 @@ class EmailAccount(Document): return None args = frappe._dict({ - "email_account":self.name, + "email_account": self.name, "host": self.email_server, "use_ssl": self.use_ssl, "username": getattr(self, "login_id", None) or self.email_id, @@ -166,21 +166,46 @@ class EmailAccount(Document): frappe.throw(_("{0} is required").format("Email Server")) email_server = EmailServer(frappe._dict(args)) + self.check_email_server_connection(email_server, in_receive) + + if not in_receive and self.use_imap: + email_server.imap.logout() + + # reset failed attempts count + self.set_failed_attempts_count(0) + + return email_server + + @classmethod + def check_email_server_connection(cls, email_server, in_receive): + # tries to connect to email server and handles failure try: email_server.connect() except (error_proto, imaplib.IMAP4.error) as e: - e = cstr(e) - message = e.lower().replace(" ","") - if in_receive and any(map(lambda t: t in message, ['authenticationfailed', 'loginviayourwebbrowser', #abbreviated to work with both failure and failed - 'loginfailed', 'err[auth]', 'errtemporaryerror'])): #temporary error to deal with godaddy - # if called via self.receive and it leads to authentication error, disable incoming - # and send email to system manager - self.handle_incoming_connect_error( - description=_('Authentication failed while receiving emails from Email Account {0}. Message from server: {1}').format(self.name, e) - ) + message = cstr(e).lower().replace(" ","") + auth_error_codes = [ + 'authenticationfailed', + 'loginfailed', + ] + other_error_codes = [ + 'err[auth]', + 'errtemporaryerror', + 'loginviayourwebbrowser' + ] + + all_error_codes = auth_error_codes + other_error_codes + + if in_receive and any(map(lambda t: t in message, all_error_codes)): + # if called via self.receive and it leads to authentication error, + # disable incoming and send email to System Manager + error_message = _('Authentication failed while receiving emails from Email Account {0}.').format(self.name) + error_message += "
" + _('Message from server: {0}').format(cstr(e)) + self.handle_incoming_connect_error(description=error_message) return None + elif not in_receive and any(map(lambda t: t in message, auth_error_codes)): + cls.throw_invalid_credentials_exception() else: frappe.throw(e) @@ -195,16 +220,16 @@ class EmailAccount(Document): else: frappe.cache().set_value("workers:no-internet", True) return None - else: raise - if not in_receive: - if self.use_imap: - email_server.imap.logout() - # reset failed attempts count - self.set_failed_attempts_count(0) - return email_server + @classmethod + def throw_invalid_credentials_exception(cls): + frappe.throw( + _("Incorrect email or password. Please check your login credentials."), + exc=frappe.ValidationError, + title=_("Invalid Credentials") + ) def handle_incoming_connect_error(self, description): if test_internet(): diff --git a/frappe/email/receive.py b/frappe/email/receive.py index 03aedec066..cf6c13ee76 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -59,10 +59,6 @@ class EmailServer: frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.')) raise - except Exception as e: - frappe.msgprint(_('Cannot connect: {0}').format(str(e))) - raise - def connect_pop(self): #this method return pop connection try: diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py index 7d179884b8..f53b835757 100644 --- a/frappe/email/smtp.py +++ b/frappe/email/smtp.py @@ -242,11 +242,8 @@ class SMTPServer: return self._sess except smtplib.SMTPAuthenticationError as e: - frappe.throw( - _("Incorrect email or password. Please check your login credentials."), - exc=frappe.ValidationError, - title=_("Invalid Credentials") - ) + from frappe.email.doctype.email_account.email_account import EmailAccount + EmailAccount.throw_invalid_credentials_exception() except _socket.error as e: # Invalid mail server -- due to refusing connection