[IMP] fetchmail: try / except the processinf of each email and log any exception

found during processing. This way, all emails in the queue are managed and
all failed emails have their own exception in the logs, allowing easier
debugging.
Note that a failed email is set as seen to avoid processing it every time
the scheduler runs.

bzr revid: tde@openerp.com-20140213095717-tcwgkl143i3ujw8h
This commit is contained in:
Thibault Delavallée 2014-02-13 10:57:17 +01:00
parent dca7f71d71
commit ec5291c130
2 changed files with 26 additions and 17 deletions

View File

@ -188,7 +188,7 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
for server in self.browse(cr, uid, ids, context=context): for server in self.browse(cr, uid, ids, context=context):
_logger.info('start checking for new emails on %s server %s', server.type, server.name) _logger.info('start checking for new emails on %s server %s', server.type, server.name)
context.update({'fetchmail_server_id': server.id, 'server_type': server.type}) context.update({'fetchmail_server_id': server.id, 'server_type': server.type})
count = 0 count, failed = 0, 0
imap_server = False imap_server = False
pop_server = False pop_server = False
if server.type == 'imap': if server.type == 'imap':
@ -197,21 +197,26 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
imap_server.select() imap_server.select()
result, data = imap_server.search(None, '(UNSEEN)') result, data = imap_server.search(None, '(UNSEEN)')
for num in data[0].split(): for num in data[0].split():
res_id = None
result, data = imap_server.fetch(num, '(RFC822)') result, data = imap_server.fetch(num, '(RFC822)')
imap_server.store(num, '-FLAGS', '\\Seen') imap_server.store(num, '-FLAGS', '\\Seen')
res_id = mail_thread.message_process(cr, uid, server.object_id.model, try:
data[0][1], res_id = mail_thread.message_process(cr, uid, server.object_id.model,
save_original=server.original, data[0][1],
strip_attachments=(not server.attach), save_original=server.original,
context=context) strip_attachments=(not server.attach),
context=context)
except Exception:
_logger.exception('Failed to process mail from %s server %s.', server.type, server.name)
failed += 1
if res_id and server.action_id: if res_id and server.action_id:
action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id], 'active_model': context.get("thread_model", server.object_id.model)}) action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids': [res_id], 'active_model': context.get("thread_model", server.object_id.model)})
imap_server.store(num, '+FLAGS', '\\Seen') imap_server.store(num, '+FLAGS', '\\Seen')
cr.commit() cr.commit()
count += 1 count += 1
_logger.info("fetched/processed %s email(s) on %s server %s", count, server.type, server.name) _logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", count, server.type, server.name, (count - failed), failed)
except Exception: except Exception:
_logger.exception("Failed to fetch mail from %s server %s.", server.type, server.name) _logger.exception("General fallure when trying to fetch mail from %s server %s.", server.type, server.name)
finally: finally:
if imap_server: if imap_server:
imap_server.close() imap_server.close()
@ -224,16 +229,20 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
for num in range(1, numMsgs + 1): for num in range(1, numMsgs + 1):
(header, msges, octets) = pop_server.retr(num) (header, msges, octets) = pop_server.retr(num)
msg = '\n'.join(msges) msg = '\n'.join(msges)
res_id = mail_thread.message_process(cr, uid, server.object_id.model, try:
msg, res_id = mail_thread.message_process(cr, uid, server.object_id.model,
save_original=server.original, msg,
strip_attachments=(not server.attach), save_original=server.original,
context=context) strip_attachments=(not server.attach),
context=context)
except Exception:
_logger.exception('Failed to process mail from %s server %s.', server.type, server.name)
failed += 1
if res_id and server.action_id: if res_id and server.action_id:
action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id], 'active_model': context.get("thread_model", server.object_id.model)}) action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids': [res_id], 'active_model': context.get("thread_model", server.object_id.model)})
pop_server.dele(num) pop_server.dele(num)
cr.commit() cr.commit()
_logger.info("fetched/processed %s email(s) on %s server %s", numMsgs, server.type, server.name) _logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", numMsgs, server.type, server.name, (numMsgs - failed), failed)
except Exception: except Exception:
_logger.exception("Failed to fetch mail from %s server %s.", server.type, server.name) _logger.exception("Failed to fetch mail from %s server %s.", server.type, server.name)
finally: finally:

View File

@ -598,7 +598,7 @@ class mail_thread(osv.AbstractModel):
thread_id = False thread_id = False
if not (thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new')): if not (thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new')):
raise ValueError( raise ValueError(
'No possible route found for incoming message from %s to %s (Message-Id %s:).' 'No possible route found for incoming message from %s to %s (Message-Id %s:). '
'Create an appropriate mail.alias or force the destination model.' % 'Create an appropriate mail.alias or force the destination model.' %
(email_from, email_to, message_id) (email_from, email_to, message_id)
) )