Merge pull request #1422 from anandpdoshi/fix/catch-pop3-exceptions

Catch 2 exceptions in pop3 receive
This commit is contained in:
Anand Doshi 2015-11-26 14:14:16 +05:30
commit bab459a4e0
4 changed files with 68 additions and 19 deletions

View file

@ -38,13 +38,13 @@ def add(args=None):
and owner=%(assign_to)s""", args):
frappe.msgprint(_("Already in user's To Do list"), raise_exception=True)
return
else:
from frappe.utils import nowdate
if args.get("re_assign"):
remove_from_todo_if_already_assigned(args['doctype'], args['name'])
d = frappe.get_doc({
"doctype":"ToDo",
"owner": args['assign_to'],
@ -56,39 +56,38 @@ def add(args=None):
"date": args.get('date', nowdate()),
"assigned_by": args.get('assigned_by', frappe.session.user),
}).insert(ignore_permissions=True)
# set assigned_to if field exists
if frappe.get_meta(args['doctype']).get_field("assigned_to"):
frappe.db.set_value(args['doctype'], args['name'], "assigned_to", args['assign_to'])
# notify
if not args.get("no_notification"):
notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN',\
description=args.get("description"), notify=args.get('notify'))
notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN',\
description=args.get("description"), notify=args.get('notify'))
if not args.get("bulk_assign"):
return get(args)
else:
return {}
@frappe.whitelist()
def add_multiple(args=None):
import json
if not args:
args = frappe.local.form_dict
docname_list = json.loads(args['name'])
for docname in docname_list:
args.update({"name": docname})
add(args)
def remove_from_todo_if_already_assigned(doctype, docname):
owner = frappe.db.get_value("ToDo", {"reference_type": doctype, "reference_name": docname, "status":"Open"}, "owner")
if owner:
remove(doctype, docname, owner)
@frappe.whitelist()
def remove(doctype, name, assign_to):
"""remove from todo"""
@ -156,5 +155,6 @@ def notify_assignment(assigned_by, owner, doc_type, doc_name, action='CLOSE',
}
arg["parenttype"] = "Assignment"
from frappe.desk.page.messages import messages
messages.post(**arg)

View file

@ -14,6 +14,9 @@ from poplib import error_proto
import re
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta
from frappe.desk.form import assign_to
from frappe.utils.user import get_system_managers
import socket
class SentEmailInInbox(Exception): pass
@ -96,7 +99,7 @@ class EmailAccount(Document):
)
server.sess
def get_pop3(self):
def get_pop3(self, in_receive=False):
"""Returns logged in POP3 connection object."""
args = {
"host": self.pop3_server,
@ -111,18 +114,56 @@ class EmailAccount(Document):
pop3 = POP3Server(frappe._dict(args))
try:
pop3.connect()
except error_proto, e:
frappe.throw(e.message)
if in_receive and e.message=="-ERR authentication failed":
# 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}'.format(self.name))
)
return None
else:
frappe.throw(e.message)
except socket.error:
if in_receive:
# timeout while connecting, see receive.py connect method
description = frappe.message_log.pop() if frappe.message_log else "Socket Error"
self.handle_incoming_connect_error(description=description)
return None
else:
raise
return pop3
def handle_incoming_connect_error(self, description):
self.db_set("enable_incoming", 0)
for user in get_system_managers(only_name=True):
assign_to.add({
'assign_to': user,
'doctype': self.doctype,
'name': self.name,
'description': description,
'priority': 'High',
'notify': 1
})
def receive(self, test_mails=None):
"""Called by scheduler to receive emails from this EMail account using POP3."""
if self.enable_incoming:
if frappe.local.flags.in_test:
incoming_mails = test_mails
else:
pop3 = self.get_pop3()
pop3 = self.get_pop3(in_receive=True)
if not pop3:
return
incoming_mails = pop3.get_messages()
exceptions = []

View file

@ -13,6 +13,14 @@ from frappe.email.doctype.email_account.email_account import notify_unreplied
from datetime import datetime, timedelta
class TestEmailAccount(unittest.TestCase):
def setUp(self):
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
email_account.db_set("enable_incoming", 1)
def tearDown(self):
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
email_account.db_set("enable_incoming", 0)
def test_incoming(self):
frappe.db.sql("delete from tabCommunication where sender='test_sender@example.com'")

View file

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import time
import _socket, poplib
import socket, poplib
import frappe
from frappe import _
from frappe.utils import extract_email_id, convert_utc_to_user_timezone, now, cint, cstr, strip
@ -48,7 +48,7 @@ class POP3Server:
# connection established!
return True
except _socket.error:
except socket.error:
# Invalid mail server -- due to refusing connection
frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.'))
raise