Skip to content

Commit e813e6e

Browse files
committed
issue2551376: Fix tracebacks in item templates
1 parent b7167fe commit e813e6e

File tree

4 files changed

+57
-9
lines changed

4 files changed

+57
-9
lines changed

CHANGES.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ Fixed:
9191
using -L and -d with roundup-server. (John Rouillard)
9292
- Allow the specification of a "form" parameter for Date fields to make
9393
the popup calendar work when the enclosing form has a name different
94-
from "itemSynopsis".
94+
from "itemSynopsis". (Ralf Schlatterbeck)
95+
- issue2551376: Fix tracebacks in item templates (Ralf Schlatterbeck)
9596

9697
Features:
9798

roundup/backends/back_postgresql.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def get_database_schema_names(config):
116116
#
117117
# Database name is any character sequence not including a " or
118118
# whitespace. Arguably both are allowed by:
119-
#
119+
#
120120
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
121121
#
122122
# with suitable quoting but ... really.
@@ -170,7 +170,7 @@ def get_database_user_name(config):
170170
#
171171
# Database name is any character sequence not including a " or
172172
# whitespace. Arguably both are allowed by:
173-
#
173+
#
174174
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
175175
#
176176
# with suitable quoting but ... really.
@@ -560,14 +560,51 @@ def clear(self):
560560
self.cursor.execute('DROP SEQUENCE _%s_ids' % cn)
561561
self.cursor.execute('CREATE SEQUENCE _%s_ids' % cn)
562562

563+
def getnode (self, classname, nodeid, fetch_multilinks=True):
564+
""" For use of savepoint see 'Class' below """
565+
self.sql('savepoint sp')
566+
try:
567+
getnode = rdbms_common.Database.getnode
568+
return getnode(self, classname, nodeid, fetch_multilinks)
569+
except psycopg2.errors.DataError as err:
570+
self.sql('rollback to savepoint sp')
571+
raise hyperdb.HyperdbValueError(str (err).split('\n')[0])
572+
563573

564574
class PostgresqlClass:
565575
order_by_null_values = '(%s is not NULL)'
566576
case_insensitive_like = 'ILIKE'
567577

568578

569579
class Class(PostgresqlClass, rdbms_common.Class):
570-
pass
580+
""" We re-raise database-specific data errors as HyperdbValueError
581+
Note that we re-use the savepoint so that at most one savepoint
582+
is used.
583+
"""
584+
585+
def filter(self, *args, **kw):
586+
self.db.sql('savepoint sp')
587+
try:
588+
return rdbms_common.Class.filter(self, *args, **kw)
589+
except psycopg2.errors.DataError as err:
590+
self.db.sql('rollback to savepoint sp')
591+
raise hyperdb.HyperdbValueError(str (err).split('\n')[0])
592+
593+
def filter_iter(self, *args, **kw):
594+
self.db.sql('savepoint sp')
595+
try:
596+
return rdbms_common.Class.filter_iter(self, *args, **kw)
597+
except psycopg2.errors.DataError as err:
598+
self.db.sql('rollback to savepoint sp')
599+
raise hyperdb.HyperdbValueError(str (err).split('\n')[0])
600+
601+
def is_retired(self, nodeid):
602+
self.db.sql('savepoint sp')
603+
try:
604+
return rdbms_common.Class.is_retired(self, nodeid)
605+
except psycopg2.errors.DataError as err:
606+
self.db.sql('rollback to savepoint sp')
607+
raise hyperdb.HyperdbValueError (str (err).split('\n')[0])
571608

572609

573610
class IssueClass(PostgresqlClass, rdbms_common.IssueClass):

roundup/backends/rdbms_common.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2248,8 +2248,15 @@ def restore(self, nodeid):
22482248
self.fireReactors('restore', nodeid, None)
22492249

22502250
def is_retired(self, nodeid):
2251-
"""Return true if the node is rerired
2251+
"""Return true if the node is retired
22522252
"""
2253+
# Do not produce invalid sql, the id must be numeric
2254+
try:
2255+
id = int(nodeid)
2256+
except ValueError:
2257+
raise hyperdb.HyperdbValueError(_(
2258+
'class %(cls)s: %(value)r is not an id')
2259+
% {'cls': self.classname, 'value': nodeid})
22532260
sql = 'select __retired__ from _%s where id=%s' % (self.classname,
22542261
self.db.arg)
22552262
self.db.sql(sql, (nodeid,))

roundup/cgi/templating.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ def __getitem__(self, item):
11221122
try:
11231123
if int(self._nodeid) > 0:
11241124
value = self._klass.get(self._nodeid, items[0], None)
1125-
except ValueError:
1125+
except (IndexError, ValueError):
11261126
value = self._nodeid
11271127
if value is None:
11281128
if isinstance(prop, hyperdb.Multilink):
@@ -2573,9 +2573,9 @@ def field(self, showid=0, size=None, **kwargs):
25732573
if k and num_re.match(self._value):
25742574
try:
25752575
value = linkcl.get(self._value, k)
2576-
except IndexError:
2576+
except (IndexError, hyperdb.HyperdbValueError) as err:
25772577
if idparse:
2578-
raise
2578+
self._client.add_error_message(str(err))
25792579
value = ''
25802580
else:
25812581
value = self._value
@@ -2880,7 +2880,10 @@ def field(self, size=30, showid=0, **kwargs):
28802880
showid = 1
28812881
if not showid:
28822882
k = linkcl.labelprop(1)
2883-
value = lookupKeys(linkcl, k, value)
2883+
try:
2884+
value = lookupKeys(linkcl, k, value)
2885+
except (ValueError, IndexError) as err:
2886+
self._client.add_error_message (str(err))
28842887
value = ','.join(value)
28852888
kwargs["value"] = value
28862889

0 commit comments

Comments
 (0)