Repository: kartoza/prj.app

Issue:
Error when spammer tries to hit sponsors page
I am getting lots of errors like this:

```python
ERROR 2018-02-20 01:59:48,578 base 500 140635683981056 Sentry responded with an error: HTTP Error 502: Bad Gateway (url: http://sentry.kartoza.com/api/8/store/)
{u'culprit': u'changes.views.sponsor in get_object',
 u'event_id': u'51eea0ac1c3c460c909906a4100c069f',
 u'exception': {u'values': [{u'module': u'changes.models.sponsorship_period',
                             u'stacktrace': {u'frames': [{u'abs_path': u'/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py',
                                                          u'context_line': u'                    response = wrapped_callback(request, *callback_args, **callback_kwargs)',
                                                          u'filename': u'django/core/handlers/base.py',
                                                          u'function': u'get_response',
                                                          u'in_app': False,
                                                          u'lineno': 132,
                                                          u'module': u'django.core.handlers.base',
                                                          u'post_context': [u'                except Exception as e:',
                                                                            u'                    # If the view raised an exception, run it through exception',
                                                                            u'                    # middleware, and if the exception middleware returns a',
                                                                            u'                    # response, use that. Otherwise, reraise the exception.',
                                                                            u'                    for middleware_method in self._exception_middleware:'],
                                                          u'pre_context': [u'                        break',
                                                                           u'',
                                                                           u'            if response is None:',
                                                                           u'                wrapped_callback = self.make_view_atomic(callback)',
                                                                           u'                try:'],
                                                          u'vars': {u'callback': u'<function SponsorDetailView from changes.views.sponsor at 0x7fe84cb06f50>',
                                                                    u'callback_args': [],
                                                                    u'callback_kwargs': {u"'project_slug'": u"u'qgis'",
                                                                                         u"'slug'": u"u'qzijic'"},
                                                                    u'e': u"DoesNotExist('SponsorshipPeriod matching query does not exist.',)",
                                                                    u'middleware_method': u'<bound method CsrfViewMiddleware.process_view of <django.middleware.csrf.CsrfViewMiddleware object at 0x7fe84e238d50>>',
                                                                    u'request': u'<WSGIRequest at 0x140635686765904>',
                                                                    u'resolver': u"<RegexURLResolver 'core.urls' (None:None) ^/>",
                                                                    u'resolver_match': u"ResolverMatch(func=changes.views.sponsor.SponsorDetailView, args=(), kwargs={'slug': u'qzijic', 'project_slug': u'qgis'}, url_name=sponsor-detail, app_name=None, namespaces=[])",
                                                                    u'response': None,
                                                                    u'self': u'<django.core.handlers.wsgi.WSGIHandler object at 0x7fe860f3bcd0>',
                                                                    u'urlconf': u"'core.urls'",
                                                                    u'wrapped_callback': u'<function SponsorDetailView from changes.views.sponsor at 0x7fe84cb06f50>'}},
                                                         {u'abs_path': u'/usr/local/lib/python2.7/site-packages/django/views/generic/base.py',
                                                          u'context_line': u'            return self.dispatch(request, *args, **kwargs)',
                                                          u'filename': u'django/views/generic/base.py',
                                                          u'function': u'view',
                                                          u'in_app': False,
                                                          u'lineno': 71,
                                                          u'module': u'django.views.generic.base',
                                                          u'post_context': [u'',
                                                                            u'        # take name and docstring from class',
                                                                            u'        update_wrapper(view, cls, updated=())',
                                                                            u'',
                                                                            u'        # and possible attributes set by decorators'],
                                                          u'pre_context': [u"            if hasattr(self, 'get') and not hasattr(self, 'head'):",
                                                                           u'                self.head = self.get',
                                                                           u'            self.request = request',
                                                                           u'            self.args = args',
                                                                           u'            self.kwargs = kwargs'],
                                                          u'vars': {u'args': [],
                                                                    u'cls': u"<class 'changes.views.sponsor.SponsorDetailView'>",
                                                                    u'initkwargs': {},
                                                                    u'kwargs': {u"'project_slug'": u"u'qgis'",
                                                                                u"'slug'": u"u'qzijic'"},
                                                                    u'request': u'<WSGIRequest at 0x140635686765904>',
                                                                    u'self': u'<changes.views.sponsor.SponsorDetailView object at 0x7fe84c0c8a10>'}},
                                                         {u'abs_path': u'/usr/local/lib/python2.7/site-packages/django/views/generic/base.py',
                                                          u'context_line': u'        return handler(request, *args, **kwargs)',
                                                          u'filename': u'django/views/generic/base.py',
                                                          u'function': u'dispatch',
                                                          u'in_app': False,
                                                          u'lineno': 89,
                                                          u'module': u'django.views.generic.base',
                                                          u'post_context': [u'',
                                                                            u'    def http_method_not_allowed(self, request, *args, **kwargs):',
                                                                            u"        logger.warning('Method Not Allowed (%s): %s', request.method, request.path,",
                                                                            u'            extra={',
                                                                            u"                'status_code'ERROR 2018-02-20 01:59:48,578 base 500 140635683981056 [u'DoesNotExist: SponsorshipPeriod matching query does not exist.', u'  File "django/core/handlers/base.py", line 132, in get_response', u'  File "django/views/generic/base.py", line 71, in view', u'  File "django/views/generic/base.py", line 89, in dispatch', u'  File "django/views/generic/detail.py", line 115, in get', u'  File "changes/views/sponsor.py", line 269, in get_object', u'  File "django/db/models/query.py", line 334, in get']
Respawned uWSGI worker 1 (new pid: 503)
```

Proposed solution - check what is going on in "changes/views/sponsor.py", line 269 and check that we handle errors gracefully there.


Discussion:
@sonlinux please check with @ann26 if she has any pending work on this otherwise take it over.

Resolving patch:
diff --git a/django_project/changes/views/sponsor.py b/django_project/changes/views/sponsor.py
--- a/django_project/changes/views/sponsor.py
+++ b/django_project/changes/views/sponsor.py
@@ -266,8 +266,11 @@ def get_object(self, queryset=None):
             project_slug = self.kwargs.get('project_slug', None)
             if slug and project_slug:
                 project = Project.objects.get(slug=project_slug)
-                obj = queryset.get(project=project, slug=slug)
-                return obj
+                try:
+                    obj = queryset.get(project=project, slug=slug)
+                    return obj
+                except:
+                    return Http404('Sorry! we could not find your sponsor.')
             else:
                 raise Http404('Sorry! We could not find your sponsor!')
 


Test patch: