Fix issue #1804: In mailer.py, any SMTP error impedes later emails
Per SVN-1804, any SMTP error terminates mailer.py with an unhandled exception. The impact is that if the same invocation of mailer.py would have sent more emails, those that would have been sent after the exception are silently lost.
To fix this issue, we handle SMTP exceptions. When an exception only affects a particular email, such as invalid recipient, the error is reported to stderr and execution continues to avoid losing any later emails. In contrast, fatal SMTP errors, such as login with bad credentials, terminate execution as before, but with some additional reporting to stderr.
The script's exit code is zero if all emails were sent successfully, nonzero if any SMTP error occurred.
* tools/hook-scripts/mailer/mailer.py (MessageSendFailure): New exception class to signify non-fatal message sending failure. This is decoupled from SMTP to allow for future use with other (non-SMTP) delivery methods. (SMTPOutput.finish): Reimplement with exception handling and reporting to stderr. (Commit.generate, PropChange.generate, Lock.generate): Wrap contents of for-loop in try..except block to handle new MessageSendFailure; after the loop runs to completion, return nonzero if SMTP error(s) occurred. (main): Propagate return value of messenger.generate() to caller. (__main__): Exit nonzero if SMTP error(s) occurred.
Found by: Robert M. Zigweid Review by: danielsh (partial review) futatuki