Skip to content

Commit 6a85324

Browse files
author
Richard Jones
committed
More error handling fixes.
1 parent f873649 commit 6a85324

File tree

2 files changed

+114
-38
lines changed

2 files changed

+114
-38
lines changed

roundup-admin

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1717
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1818
#
19-
# $Id: roundup-admin,v 1.42 2001-11-09 10:11:08 richard Exp $
19+
# $Id: roundup-admin,v 1.43 2001-11-09 22:33:28 richard Exp $
2020

2121
import sys
2222
if int(sys.version[0]) < 2:
@@ -287,7 +287,7 @@ Command help:
287287
raise UsageError, 'argument "%s" not propname=value'%prop
288288
try:
289289
key, value = prop.split('=')
290-
except (TypeError, ValueError):
290+
except ValueError:
291291
raise UsageError, 'argument "%s" not propname=value'%prop
292292
props[key] = value
293293
for designator in designators:
@@ -352,7 +352,7 @@ Command help:
352352
raise UsageError, 'argument "%s" not propname=value'%prop
353353
try:
354354
propname, value = args[1].split('=')
355-
except (TypeError, ValueError):
355+
except ValueError:
356356
raise UsageError, 'argument "%s" not propname=value'%prop
357357

358358
# if the value isn't a number, look up the linked class to get the
@@ -460,7 +460,7 @@ Command help:
460460
raise UsageError, 'argument "%s" not propname=value'%prop
461461
try:
462462
key, value = prop.split('=')
463-
except (TypeError, ValueError):
463+
except ValueError:
464464
raise UsageError, 'argument "%s" not propname=value'%prop
465465
props[key] = value
466466

@@ -882,6 +882,9 @@ if __name__ == '__main__':
882882

883883
#
884884
# $Log: not supported by cvs2svn $
885+
# Revision 1.42 2001/11/09 10:11:08 richard
886+
# . roundup-admin now handles all hyperdb exceptions
887+
#
885888
# Revision 1.41 2001/11/09 01:25:40 richard
886889
# Should parse with python 1.5.2 now.
887890
#

roundup/mailgw.py

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,17 @@ class node. Any parts of other types are each stored in separate files
7272
an exception, the original message is bounced back to the sender with the
7373
explanatory message given in the exception.
7474
75-
$Id: mailgw.py,v 1.29 2001-11-07 05:29:26 richard Exp $
75+
$Id: mailgw.py,v 1.30 2001-11-09 22:33:28 richard Exp $
7676
'''
7777

7878

7979
import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
8080
import traceback
8181
import hyperdb, date, password
8282

83+
class MailGWError(ValueError):
84+
pass
85+
8386
class MailUsageError(ValueError):
8487
pass
8588

@@ -129,41 +132,63 @@ def handle_Message(self, message):
129132
handle errors in a different manner.
130133
'''
131134
m = []
132-
try:
133-
self.handle_message(message)
134-
except MailUsageError, value:
135-
# bounce the message back to the sender with the usage message
136-
fulldoc = '\n'.join(string.split(__doc__, '\n')[2:])
137-
sendto = [message.getaddrlist('from')[0][1]]
138-
m = ['Subject: Failed issue tracker submission', '']
139-
m.append(str(value))
140-
m.append('\n\nMail Gateway Help\n=================')
141-
m.append(fulldoc)
142-
except:
143-
# bounce the message back to the sender with the error message
144-
sendto = [message.getaddrlist('from')[0][1]]
145-
m = ['Subject: failed issue tracker submission']
135+
# in some rare cases, a particularly stuffed-up e-mail will make
136+
# its way into here... try to handle it gracefully
137+
sendto = message.getaddrlist('from')
138+
if sendto:
139+
try:
140+
self.handle_message(message)
141+
return
142+
except MailUsageError, value:
143+
# bounce the message back to the sender with the usage message
144+
fulldoc = '\n'.join(string.split(__doc__, '\n')[2:])
145+
sendto = [sendto[0][1]]
146+
m = ['Subject: Failed issue tracker submission', '']
147+
m.append(str(value))
148+
m.append('\n\nMail Gateway Help\n=================')
149+
m.append(fulldoc)
150+
except:
151+
# bounce the message back to the sender with the error message
152+
sendto = [sendto[0][1]]
153+
m = ['Subject: failed issue tracker submission']
154+
m.append('')
155+
# TODO as attachments?
156+
m.append('---- traceback of failure ----')
157+
s = cStringIO.StringIO()
158+
import traceback
159+
traceback.print_exc(None, s)
160+
m.append(s.getvalue())
161+
m.append('---- failed message follows ----')
162+
try:
163+
message.fp.seek(0)
164+
except:
165+
pass
166+
m.append(message.fp.read())
167+
else:
168+
# very bad-looking message - we don't even know who sent it
169+
sendto = [self.ADMIN_EMAIL]
170+
m = ['Subject: badly formed message from mail gateway']
171+
m.append('')
172+
m.append('The mail gateway retrieved a message which has no From:')
173+
m.append('line, indicating that it is corrupt. Please check your')
174+
m.append('mail gateway source.')
146175
m.append('')
147-
# TODO as attachments?
148-
m.append('---- traceback of failure ----')
149-
s = cStringIO.StringIO()
150-
import traceback
151-
traceback.print_exc(None, s)
152-
m.append(s.getvalue())
153176
m.append('---- failed message follows ----')
154177
try:
155178
message.fp.seek(0)
156179
except:
157180
pass
158181
m.append(message.fp.read())
159-
if m:
160-
try:
161-
smtp = smtplib.SMTP(self.MAILHOST)
162-
smtp.sendmail(self.ADMIN_EMAIL, sendto, '\n'.join(m))
163-
except socket.error, value:
164-
return "Couldn't send confirmation email: mailhost %s"%value
165-
except smtplib.SMTPException, value:
166-
return "Couldn't send confirmation email: %s"%value
182+
183+
# now send the message
184+
try:
185+
smtp = smtplib.SMTP(self.MAILHOST)
186+
smtp.sendmail(self.ADMIN_EMAIL, sendto, '\n'.join(m))
187+
except socket.error, value:
188+
raise MailGWError, "Couldn't send confirmation email: "\
189+
"mailhost %s"%value
190+
except smtplib.SMTPException, value:
191+
raise MailGWError, "Couldn't send confirmation email: %s"%value
167192

168193
def handle_message(self, message):
169194
''' message - a Message instance
@@ -242,9 +267,25 @@ def handle_message(self, message):
242267
if isinstance(type, hyperdb.Password):
243268
props[key] = password.Password(value)
244269
elif isinstance(type, hyperdb.Date):
245-
props[key] = date.Date(value)
270+
try:
271+
props[key] = date.Date(value)
272+
except ValueError, message:
273+
raise UsageError, '''
274+
Subject argument list contains an invalid date for %s.
275+
276+
Error was: %s
277+
Subject was: "%s"
278+
'''%(key, message, subject)
246279
elif isinstance(type, hyperdb.Interval):
247-
props[key] = date.Interval(value)
280+
try:
281+
props[key] = date.Interval(value)
282+
except ValueError, message:
283+
raise UsageError, '''
284+
Subject argument list contains an invalid date interval for %s.
285+
286+
Error was: %s
287+
Subject was: "%s"
288+
'''%(key, message, subject)
248289
elif isinstance(type, hyperdb.Link):
249290
props[key] = value
250291
elif isinstance(type, hyperdb.Multilink):
@@ -386,7 +427,13 @@ def handle_message(self, message):
386427
props['status'] == resolved_id):
387428
props['status'] = chatting_id
388429

389-
cl.set(nodeid, **props)
430+
try:
431+
cl.set(nodeid, **props)
432+
except (TypeError, IndexError, ValueError), message:
433+
raise MailUsageError, '''
434+
There was a problem with the message you sent:
435+
%s
436+
'''%message
390437
else:
391438
# If just an item class name is found there, we attempt to create a
392439
# new item of that class with its "messages" property initialized to
@@ -399,15 +446,35 @@ def handle_message(self, message):
399446
if properties.has_key('assignedto') and \
400447
not props.has_key('assignedto'):
401448
props['assignedto'] = '1' # "admin"
449+
450+
# pre-set the issue to unread
402451
if properties.has_key('status') and not props.has_key('status'):
403-
props['status'] = '1' # "unread"
452+
try:
453+
# determine the id of 'unread'
454+
unread_id = self.db.status.lookup('unread')
455+
except KeyError:
456+
pass
457+
else:
458+
props['status'] = '1'
459+
460+
# set the title to the subject
404461
if properties.has_key('title') and not props.has_key('title'):
405462
props['title'] = title
463+
464+
# pre-load the messages list and nosy list
406465
props['messages'] = [message_id]
407466
props['nosy'] = props.get('nosy', []) + recipients
408467
props['nosy'].append(author)
409468
props['nosy'].sort()
410-
nodeid = cl.create(**props)
469+
470+
# and attempt to create the new node
471+
try:
472+
nodeid = cl.create(**props)
473+
except (TypeError, IndexError, ValueError), message:
474+
raise MailUsageError, '''
475+
There was a problem with the message you sent:
476+
%s
477+
'''%message
411478

412479
def parseContent(content, blank_line=re.compile(r'[\r\n]+\s*[\r\n]+'),
413480
eol=re.compile(r'[\r\n]+'), signature=re.compile(r'^[>|\s]*[-_]+\s*$')):
@@ -449,6 +516,12 @@ def parseContent(content, blank_line=re.compile(r'[\r\n]+\s*[\r\n]+'),
449516

450517
#
451518
# $Log: not supported by cvs2svn $
519+
# Revision 1.29 2001/11/07 05:29:26 richard
520+
# Modified roundup-mailgw so it can read e-mails from a local mail spool
521+
# file. Truncates the spool file after parsing.
522+
# Fixed a couple of small bugs introduced in roundup.mailgw when I started
523+
# the popgw.
524+
#
452525
# Revision 1.28 2001/11/01 22:04:37 richard
453526
# Started work on supporting a pop3-fetching server
454527
# Fixed bugs:

0 commit comments

Comments
 (0)