diff --git a/parsedmarc/__init__.py b/parsedmarc/__init__.py index 9a33aec..795d222 100644 --- a/parsedmarc/__init__.py +++ b/parsedmarc/__init__.py @@ -1177,8 +1177,7 @@ def get_dmarc_reports_from_inbox(host=None, except imapclient.exceptions.IMAPClientError as error: error = error.__str__().lstrip("b'").rstrip("'").rstrip(".") # Workaround for random Exchange/Office365 IMAP errors - if "Server Unavailable" in error or "BAD" in error or \ - "Connection reset" in error: + if "unexpected response" in error or "BAD" in error: sleep_minutes = 5 logger.debug( "{0}. " @@ -1213,7 +1212,31 @@ def get_dmarc_reports_from_inbox(host=None, except ConnectionRefusedError: raise IMAPError("Connection refused") except ConnectionResetError: - raise IMAPError("Connection reset") + sleep_minutes = 5 + logger.debug( + "Connection reset. " + "Waiting {0} minutes before trying again".format(sleep_minutes)) + time.sleep(sleep_minutes * 60) + results = get_dmarc_reports_from_inbox( + host=host, + user=user, + password=password, + connection=connection, + port=port, + ssl=ssl, + ssl_context=ssl_context, + move_supported=move_supported, + reports_folder=reports_folder, + archive_folder=archive_folder, + delete=delete, + test=test, + nameservers=nameservers, + dns_timeout=dns_timeout, + strip_attachment_payloads=strip_attachment_payloads, + results=results + ) + + return results except ConnectionAbortedError: raise IMAPError("Connection aborted") except TimeoutError: @@ -1469,8 +1492,7 @@ def watch_inbox(host, username, password, callback, port=None, ssl=True, except imapclient.exceptions.IMAPClientError as error: error = error.__str__().replace("b'", "").replace("'", "") # Workaround for random Exchange/Office365 IMAP errors - if "Server Unavailable" in error or "BAD" in error or \ - "Connection reset" in error: + if "unexpected response" in error or "BAD" in error: sleep_minutes = 5 logger.debug( "{0}. " @@ -1606,8 +1628,7 @@ def watch_inbox(host, username, password, callback, port=None, ssl=True, except imapclient.exceptions.IMAPClientError as error: error = error.__str__().replace("b'", "").replace("'", "") # Workaround for random Exchange/Office365 IMAP errors - if "Server Unavailable" in error or "BAD" in error or \ - "Connection reset" in error: + if "unexpected response" in error or "BAD" in error: sleep_minutes = 5 logger.debug( "{0}. " @@ -1630,7 +1651,8 @@ def watch_inbox(host, username, password, callback, port=None, ssl=True, dns_timeout=dt) callback(res) server.idle() - raise IMAPError(error) + else: + raise IMAPError(error) except socket.gaierror: raise IMAPError("DNS resolution failed") except ConnectionRefusedError: diff --git a/parsedmarc/cli.py b/parsedmarc/cli.py index fdd5635..c069bcf 100644 --- a/parsedmarc/cli.py +++ b/parsedmarc/cli.py @@ -388,13 +388,17 @@ def _main(): ssl_context.verify_mode = CERT_NONE if args.imap_no_ssl: ssl = False - sa = args.strip_attachment_payloads - watch_inbox(args.host, args.user, args.password, process_reports, - port=args.imap_port, ssl=ssl, ssl_context=ssl_context, - reports_folder=args.reports_folder, - archive_folder=args.archive_folder, delete=args.delete, - test=args.test, nameservers=args.nameservers, - dns_timeout=args.timeout, strip_attachment_payloads=sa) + try: + sa = args.strip_attachment_payloads + watch_inbox(args.host, args.user, args.password, process_reports, + port=args.imap_port, ssl=ssl, ssl_context=ssl_context, + reports_folder=args.reports_folder, + archive_folder=args.archive_folder, delete=args.delete, + test=args.test, nameservers=args.nameservers, + dns_timeout=args.timeout, strip_attachment_payloads=sa) + except IMAPError as error: + logger.error("IMAP error: {0}".format(error.__str__())) + exit(1) if __name__ == "__main__":