error handling - Python try / except issue with SMTPLib -
i've written simple smtp client using python's smtplib. trying add error handling - in instance, when target server connect unavailable (eg, wrong ip specified!)
currently, traceback looks this:
traceback (most recent call last): file "<stdin>", line 1, in <module> file "smtplib_client.py", line 91, in runclient try: file "/usr/local/lib/python2.7/smtplib.py", line 251, in __init__ (code, msg) = self.connect(host, port) file "/usr/local/lib/python2.7/smtplib.py", line 311, in connect self.sock = self._get_socket(host, port, self.timeout) file "/usr/local/lib/python2.7/smtplib.py", line 286, in _get_socket return socket.create_connection((host, port), timeout) file "/usr/local/lib/python2.7/socket.py", line 571, in create_connection raise err socket.error: [errno 111] connection refused
so clearly, it's "create_connection" in socket.py going bang. has it's own try / except block:
for res in getaddrinfo(host, port, 0, sock_stream): af, socktype, proto, canonname, sa = res sock = none try: sock = socket(af, socktype, proto) if timeout not _global_default_timeout: sock.settimeout(timeout) if source_address: sock.bind(source_address) sock.connect(sa) return sock except error _: err = _ if sock not none: sock.close() if err not none: raise err else: raise error("getaddrinfo returns empty list")
my runclient() function looks like:
def runclient(configname = 'default', testfile = './test.xml'): clicfg = getclientconfig(configname) print clicfg.find('logfile').text # startlogger(clicfg.find('logfile').text) clientcert = clicfg.find('cert').text clientkey = clicfg.find('key').text serverhost = clicfg.find('serverhost').text serverport = int(clicfg.find('serverport').text) mymail = mailmessagehandler() msgsrc = mymail.readmessagesource(testfile) allmsgs = mymail.processmessages(msgsrc) inx = 1 msg in allmsgs: validmsg = true requiredkeys = ('ehlo', 'sndr', 'rcpt', 'body') msgitems in requiredkeys: if len(msg[msgitems]) == 0: validmsg = false if validmsg: try: server = smtplib.smtp(serverhost, serverport) server.ehlo(msg['ehlo']) thissender = msg['sndr'] thisrecipient = msg['rcpt'] thismessage = mimetext(msg['body']) thismessage['to'] = email.utils.formataddr(('', thisrecipient)) thismessage['from'] = email.utils.formataddr(('', thissender)) thismessage['subject'] = msg['subject'] thismessage['message-id'] = email.utils.make_msgid() = datetime.now() day = now.strftime('%a') date = now.strftime('%d %b %y %x') thismessage['date'] = day + ', ' + date + ' -0000' if msg['tls'].lower() == 'true': server.starttls('certs/client/client.key', 'certs/client/client.crt') logging.info ("message: " + thismessage['message-id'] + " sent on tls") server.sendmail(thissender, thisrecipient.split(","), thismessage.as_string()) logging.info ("message: " + thismessage['message-id'] + " sent " + serverhost + ":" + clicfg.find('serverport').text) logging.info ("message: " + thismessage['message-id'] + " had sender: " + thismessage['from']) logging.info ("message: " + thismessage['message-id'] + " had recipient(s): " + thismessage['to']) except socket.error e: print "could not connect server - down? ({0}): {1}".format(e.strerrror) except: print "unknown error:", sys.exc_info()[0] finally: server.quit() else: print "improperly formatted source mail - please check"
what don't - traceback shows call raise err
. err
not none, , must set part of except error _:
.... error handled, part of handler, copy created (err
) - subsequently raised outside of try/except block - unhandled. unhandled error should "passed up" call stack (get_socket
has no try/except block, nor connect
or __init__
- outside of try/except block original error
in create_connection
, copy of error, err
should surely "cascade" try/except block in runclient function?
following on support @andreysobolev got following simple code working fine:
import smtplib, socket try: mylib = smtplib.smtp("127.0.0.1", 25) except socket.error e: print "could not connect"
so returned smtplib_client.py, , block commented out of "try" section. worked fine... bit bit, reinstated more , more of try section.... , each , every time worked fine. final version below. other in except socket.error
handler, can't aware of have changed - other added server = none
stop finally
section working. oh, , had add "socket" list of imports. without understand except not handling correctly - don't understand why wasn't firing @ all, or generating "not defined" error.... odd!
working code:
def runclient(configname = 'default', testfile = './test.xml'): clicfg = getclientconfig(configname) print clicfg.find('logfile').text # startlogger(clicfg.find('logfile').text) clientcert = clicfg.find('cert').text clientkey = clicfg.find('key').text serverhost = clicfg.find('serverhost').text serverport = int(clicfg.find('serverport').text) mymail = mailmessagehandler() msgsrc = mymail.readmessagesource(testfile) allmsgs = mymail.processmessages(msgsrc) inx = 1 msg in allmsgs: validmsg = true requiredkeys = ('ehlo', 'sndr', 'rcpt', 'body') msgitems in requiredkeys: if len(msg[msgitems]) == 0: validmsg = false if validmsg: try: server = none server = smtplib.smtp(serverhost, serverport) server.ehlo(msg['ehlo']) thissender = msg['sndr'] thisrecipient = msg['rcpt'] thismessage = mimetext(msg['body']) thismessage['to'] = email.utils.formataddr(('', thisrecipient)) thismessage['from'] = email.utils.formataddr(('', thissender)) thismessage['subject'] = msg['subject'] thismessage['message-id'] = email.utils.make_msgid() = datetime.now() day = now.strftime('%a') date = now.strftime('%d %b %y %x') thismessage['date'] = day + ', ' + date + ' -0000' if msg['tls'].lower() == 'true': server.starttls('certs/client/client.key', 'certs/client/client.crt') logging.info ("message: " + thismessage['message-id'] + " sent on tls") server.sendmail(thissender, thisrecipient.split(","), thismessage.as_string()) logging.info ("message: " + thismessage['message-id'] + " sent " + serverhost + ":" + clicfg.find('serverport').text) logging.info ("message: " + thismessage['message-id'] + " had sender: " + thismessage['from']) logging.info ("message: " + thismessage['message-id'] + " had recipient(s): " + thismessage['to']) except socket.error e: logging.error ("could not connect " + serverhost + ":" + clicfg.find('serverport').text + " - listening / up?") except: print "unknown error:", sys.exc_info()[0] finally: if server != none: server.quit() else: print "improperly formatted source mail - please check"
baffled, yet relieved! andrey!
Comments
Post a Comment