[Twisted-Python] How to use defer.fail better...
Jan Bakuwel
jan.bakuwel at omiha.com
Mon Mar 30 03:42:01 MDT 2009
Hoi all,
I'm writing a twisted/python SMTP server that accepts emails from a MTA
using twisted. All works well, except that when I return a
defer.fail(None) from processEmail to messageHandler.eomReceived (see
below), twisted dumps the trace back of the last exception on stdout. Is
there a way to avoid this? I would like to handle the exception
gracefully (with an exception handler) and would not like to see any
trace back from it in my logs. I've read that using None as the
parameter to defer.fail does exactly that... what should I use instead?
The other thing I would like to do better is to have a way to return
smtp code 421 (service temporarily unavailable) rather than 550 (fatal)
in those cases where I would like to indicate a (temporary) failure to
receive the email. I've patched smtp.py (replace 550 -> 421) for this
but would gladly hear about a way to do this without patching a standard
component on my system.
thanks,
Jan
class messageHandler(object):
implements(smtp.IMessage)
def __init__(self, addressee):
self.lines = []
self.noisy = False
self.emailMessage = None
self.emailAddress = str(addressee)
#__init__
def lineReceived(self, line):
self.lines.append(line)
#lineReceived
def eomReceived(self):
# message is complete, store it
self.lines.append('') # add a trailing newline
messageData = '\n'.join(self.lines)
emailMessage = message_from_string(messageData)
return processEmail(self.emailAddress, emailMessage)
#eomReceived
def connectionLost(self):
log(1, 'Connection lost unexpectedly!')
# unexpected loss of connection; don't save
del(self.lines)
del(self.emailMessage)
#connectionLost
#messageHandler
class localDelivery(object):
implements(smtp.IMessageDelivery)
def __init__(self):
pass
#end __init__
def validateFrom(self, helo, originAddress):
log (1, 'Incoming email from %s', str(originAddress))
# accept mail from anywhere. To reject an address, raise
# smtp.SMTPBadSender here.
return originAddress
#end validateFrom
def receivedHeader(self, helo, origin, recipients):
myHostname, clientIP = helo
headerValue = "by %s from %s with ESMTP ; %s" % (myHostname,
clientIP, smtp.rfc822date())
log(1, '...received: %s', headerValue)
# email.Header.Header used for automatic wrapping of long lines
return "Received: %s" % Header(headerValue)
#end receivedHeader
def validateTo(self, user):
#if not user.dest.domain in valid_domains:
# print "Not accepting mail for %s" % user.dest
# raise smtp.SMTPBadRcpt(user)
log(1, 'Accepting email for %s', user.dest)
return lambda: messageHandler(user.dest)
#end validateTo
#localDelivery
class SMTPFactory(protocol.ServerFactory):
def __init__(self):
pass
#end __init__
def buildProtocol(self, addr):
delivery = localDelivery()
smtpProtocol = smtp.SMTP(delivery)
smtpProtocol.factory = self
return smtpProtocol
#buildProtocol
#SMTPFactory
More information about the Twisted-Python
mailing list