diff --git a/django/website/dashboard/templatetags/render_widget.py b/django/website/dashboard/templatetags/render_widget.py
index e9de818e4e26ce5f3f65760b9103bdc03bf3ac60..175ea4a9dbe41215b0aa2f749d70d0a4917c79e2 100644
--- a/django/website/dashboard/templatetags/render_widget.py
+++ b/django/website/dashboard/templatetags/render_widget.py
@@ -4,7 +4,7 @@ from django import template
 from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
 
-from dashboard.widget_pool import get_widget, MissingWidgetType
+from dashboard.widget_pool import get_widget, MissingWidgetType, WidgetError
 
 
 logger = logging.getLogger(__name__)
@@ -53,6 +53,10 @@ def render_widget(widget_instance):
             context = widget.get_context_data(**settings)
         except AttributeError:
             context = {}
+        except WidgetError as e:
+            template_name = 'dashboard/widget-error.html'
+            context = {}
+            context['error'] = str(e)
         except Exception as e:
             logger.exception('Error while fetching widget context data: %s', e)
             template_name = 'dashboard/widget-error.html'
diff --git a/django/website/dashboard/tests/widget_tests.py b/django/website/dashboard/tests/widget_tests.py
index 2b69bc3326e97cee9a4961087bde2f175c569fcf..fed0612ba71f7909d529ab3a3bf8b4a94775577a 100644
--- a/django/website/dashboard/tests/widget_tests.py
+++ b/django/website/dashboard/tests/widget_tests.py
@@ -3,7 +3,7 @@ from mock import patch
 from django.test import TestCase
 
 from dashboard.templatetags.render_widget import render_widget
-from dashboard.widget_pool import register_widget, get_widget
+from dashboard.widget_pool import register_widget, get_widget, WidgetError
 
 
 class TestWidget(object):
@@ -38,6 +38,26 @@ class TestWidgetNoTemplateName(object):
         return {}
 
 
+class TestWidgetRaisesException(object):
+    """ A test widget which raises a generic exception in
+        get_context_data
+    """
+    template_name = 'something.hmtl'
+
+    def get_context_data(self, **kwargs):
+        raise Exception('message raised from get_context_data')
+
+
+class TestWidgetRaisesWidgetError(object):
+    """ A test widget which raises a WidgetError in
+        get_context_data
+    """
+    template_name = 'something.html'
+
+    def get_context_data(self, **kwargs):
+        raise WidgetError('message raised from get_context_data')
+
+
 class MockWidgetInstance(object):
     """ A Mock class to represent a widget instance
 
@@ -152,3 +172,48 @@ class WidgetPoolTestCase(TestCase):
         self.assertEqual(
             template_name, 'dashboard/widget-error.html'
         )
+
+    def test_render_widget_exception_includes_generic_message(self):
+        """ Test that a widget which raises a generic exception will
+            display a generic error message, not the content of the
+            exception
+        """
+        test_widget = TestWidgetRaisesException()
+        register_widget('test-widget', test_widget)
+        widget_instance = MockWidgetInstance('test-widget')
+        with patch(self.render_to_string_method) as mock:
+            render_widget(widget_instance)
+            template_name = self.get_mock_render_to_string_parameter(
+                mock, 'template_name'
+            )
+            context = self.get_mock_render_to_string_parameter(
+                mock, 'context'
+            )
+        self.assertEqual(
+            template_name, 'dashboard/widget-error.html'
+        )
+        self.assertEqual(
+            context['error'], 'Widget error. See error logs.'
+        )
+
+    def test_render_widget_widgeterror_exception_includes_error_message(self):
+        """ Test that a widget which raises a WidgetError exception will
+            display the error message provided in the exception.
+        """
+        test_widget = TestWidgetRaisesWidgetError()
+        register_widget('test-widget', test_widget)
+        widget_instance = MockWidgetInstance('test-widget')
+        with patch(self.render_to_string_method) as mock:
+            render_widget(widget_instance)
+            template_name = self.get_mock_render_to_string_parameter(
+                mock, 'template_name'
+            )
+            context = self.get_mock_render_to_string_parameter(
+                mock, 'context'
+            )
+        self.assertEqual(
+            template_name, 'dashboard/widget-error.html'
+        )
+        self.assertEqual(
+            str(context['error']), 'message raised from get_context_data'
+        )
diff --git a/django/website/dashboard/widget_pool.py b/django/website/dashboard/widget_pool.py
index 98cc08bc6c92c660e979490e8a1074b516db8f9e..83bc41577f503bddd040d69e6ac87429a80bfa75 100644
--- a/django/website/dashboard/widget_pool.py
+++ b/django/website/dashboard/widget_pool.py
@@ -6,6 +6,17 @@ class MissingWidgetType(Exception):
     pass
 
 
+class WidgetError(Exception):
+    """ Exception that can be raised from widget types
+        in get_context_data.
+
+        The error message will be displayed to the end
+        user, so should not contain debug or sensisitve
+        information
+    """
+    pass
+
+
 def register_widget(name, widget):
     """ Register a new widget type