2

I've searched a fair bit on this and couldn't come up with anything satisfactory.

I've been trying to write a python program to listen for email bounce reports and depending on the reason for the bounce resend them at different intervals.

import smtplib
from smtplib import *

sender = 'foo@bar.com'
receivers = ['42@life.com']

message = """From: From Arthur <foo@bar.com>
To: To Deep Thought <42@life.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""

try:
  smtpObj = smtplib.SMTP('smtp.gmail.com',587)
  smtpObj.starttls()
  smtpObj.login(sender,'foo@bar.com')
  smtpObj.sendmail(sender, receivers, message)
  print "Successfully sent email"
except SMTPResponseException:
  error_code = SMTPResponseException.smtp_code
  error_message = SMTPResponseException.smtp_error
  print "Error code:"+error_code
  print "Message:"+error_message
  if (error_code==422):
    print "Recipient Mailbox Full"
  elif(error_code==431):
    print "Server out of space"
  elif(error_code==447):
    print "Timeout. Try reducing number of recipients"
  elif(error_code==510 or error_code==511):
    print "One of the addresses in your TO, CC or BBC line doesn't exist. Check again your recipients' accounts and correct any possible misspelling."
  elif(error_code==512):
    print "Check again all your recipients' addresses: there will likely be an error in a domain name (like mail@domain.coom instead of mail@domain.com)"
  elif(error_code==541 or error_code==554):
    print "Your message has been detected and labeled as spam. You must ask the recipient to whitelist you"
  elif(error_code==550):
    print "Though it can be returned also by the recipient's firewall (or when the incoming server is down), the great majority of errors 550 simply tell that the recipient email address doesn't exist. You should contact the recipient otherwise and get the right address."
  elif(error_code==553):
    print "Check all the addresses in the TO, CC and BCC field. There should be an error or a misspelling somewhere."
  else:
    print error_code+": "+error_message

To which I get the following error:

Traceback (most recent call last): File "C:/Users/Varun Shijo/PycharmProjects/EmailBounce/EmailBounceTest.py", line 20, in error_code = SMTPResponseException.smtp_code AttributeError: type object 'SMTPResponseException' has no attribute 'smtp_code'

I read somewhere that I should be trying to get the attribute from an instance of the SMTPResponseException class (even though the smtplib documentation says otheriwse) so I tried that too, but I wasn't sure of what arguments to pass its constructor (code,msg).

Could someone please nudge me in the right direction?

Thanks.

Varun Shijo
  • 35
  • 1
  • 1
  • 4

2 Answers2

7

try with

except SMTPResponseException as e:
    error_code = e.smtp_code
    error_message = e.smtp_error
Pynchia
  • 10,996
  • 5
  • 34
  • 43
  • Thank you so much! This worked. If I understand correctly, by doing that you're handling the instantiation by implicitly passing the arguments to the constructor when an exception is caught, right? – Varun Shijo Nov 07 '15 at 05:31
  • Hello. The exception is instantiated when it's raised. The code I have provided just says to python to create a name for it `e`. The attributes are set by the constructor of the exception class. Please have a look at [this SO QA](http://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python) – Pynchia Nov 07 '15 at 06:27
0

We can add more error code with error details on SMTP_ERROR_CODES dict.

import smtplib
from bs4 import BeautifulSoup
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


SMTP_ERROR_CODES = {
    211: "System status, or system help reply.",
    214: "Help message.",
    220: "Service ready.",
    221: "Service closing transmission channel.",
    235: "Authentication successful.",
    250: "Requested mail action okay, completed.",
    251: "User not local; will forward to {}",
    252: "Cannot VRFY user, but will accept message and attempt delivery.",
    354: "Start mail input; end with <CRLF>.<CRLF>",
    421: "Service not available, closing transmission channel. The server response was: {}",
    450: "Requested mail action not taken: mailbox unavailable. The server response was: {}",
    451: "Requested action aborted: local error in processing.",
    452: "Requested action not taken: insufficient system storage.",
    455: "Server unable to accommodate parameters.",
    500: "Syntax error, command unrecognized.",
    501: "Syntax error in parameters or arguments.",
    502: "Command not implemented.",
    503: "Bad sequence of commands.",
    504: "Command parameter not implemented.",
    530: "Authentication required.",
    534: "Authentication mechanism is too weak.",
    535: "Authentication failed. The server response was: {}",
    538: "Encryption required for requested authentication mechanism.",
    550: "Requested action not taken: mailbox unavailable. The server response was: {}",
    551: "User not local; please try {}. The server response was: {}",
    552: "Requested mail action aborted: exceeded storage allocation.",
    553: "Requested action not taken: mailbox name not allowed.",
    554: "Transaction failed. The server response was: {}",
}

    try:
        msg = MIMEMultipart(
            "alternative", None, [MIMEText(html_content, 'html')])
        msg['From'] = sender
        msg['To'] = ", ".join(recipients)
        msg['Subject'] = f"email report.!"
        server = smtplib.SMTP('example.com', 587)
        server.starttls()
        text = msg.as_string()
        server.sendmail(sender, recipients, text)
        server.quit()
        log.info("Successfully result was sent to the recipient email")
    except smtplib.SMTPResponseException as err:
        error_code = err.smtp_code
        error_message = SMTP_ERROR_CODES.get(error_code, f"Unknown error ({error_code})")
        log.error(f"Observed exception while send email to recipient email!,\n "
                  f"Exception: {error_message.format(err.smtp_error)}")
    except Exception as Err:
        log.error(f"Observed exception while send email to recipient email!,\n "
                  f"Exception: {Err}")
muthukumar
  • 71
  • 1
  • 4