From cd40196ec236385a23897d90f15bf6e1f0076812 Mon Sep 17 00:00:00 2001 From: Julie Pichon Date: Wed, 13 Mar 2013 15:59:45 +0000 Subject: [PATCH] Handle failures on column filters more gracefully With certain inputs it's possible for filters to fail, however we should still display the table as well as return the data we have even if it didn't go through one filter successfully. We're still expecting "filters" to be made of functions, therefore the func_name attribute should exist. Note that this warning message being displayed still indicates that there is a programming error somewhere that should be fixed. Related-Bug: #1286959 Change-Id: I408dc9fbdaa7dfe49a39ad3a96a0e1256f6a99eb --- horizon/tables/base.py | 9 ++++++++- horizon/test/tests/tables.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/horizon/tables/base.py b/horizon/tables/base.py index eb34512589..b6c3dbe2b1 100644 --- a/horizon/tables/base.py +++ b/horizon/tables/base.py @@ -347,7 +347,14 @@ class Column(html.HTMLElement): data = display_value[0] else: for filter_func in self.filters: - data = filter_func(data) + try: + data = filter_func(data) + except Exception: + msg = ("Filter '%(filter)s' failed with data " + "'%(data)s' on column '%(col_name)s'") + LOG.warning(msg, {'filter': filter_func.func_name, + 'data': data, + 'col_name': unicode(self.verbose_name)}) if data and self.truncate: data = truncatechars(data, self.truncate) diff --git a/horizon/test/tests/tables.py b/horizon/test/tests/tables.py index 64bba3d52f..e0f59eefd9 100644 --- a/horizon/test/tests/tables.py +++ b/horizon/test/tests/tables.py @@ -18,6 +18,7 @@ from django.core.urlresolvers import reverse from django import forms from django import http from django import shortcuts +from django.template import defaultfilters from mox import IsA # noqa @@ -1091,6 +1092,19 @@ class DataTableTests(test.TestCase): row = self.table.get_rows()[0] self.assertTrue("down" in row.cells['status'].value) + def test_broken_filter(self): + class MyTableBrokenFilter(MyTable): + value = tables.Column('value', + filters=(defaultfilters.timesince,)) + + value = "not_a_date" + data = TEST_DATA[0] + data.value = value + + table = MyTableBrokenFilter(self.request, [data]) + resp = http.HttpResponse(table.render()) + self.assertContains(resp, value) + class SingleTableView(table_views.DataTableView): table_class = MyTable