Invalid BannerImage in affiliate link causes error on a user's my_banners page

VERIFIED FIXED in 1.0

Status

Firefox Affiliates Graveyard
affiliates.mozilla.org
--
critical
VERIFIED FIXED
6 years ago
2 years ago

People

(Reporter: mkelly, Assigned: mkelly)

Tracking

unspecified

Details

(Whiteboard: [dev])

(Assignee)

Description

6 years ago
1. Create an affiliate link, like /link/banner/1/1/1
2. Alter the third number (banner image id) to an invalid id (/link/banner/1/1/1000)
3. Follow the link
4. Log in as the user for whom the link was created (user with id 1)
5. Observe the My Banners page

A DoesNotExist error is thrown at this point. 

The reason is that, when following the affiliate link, the app creates a bannerinstance based on the parameters passed in the URL. Because bannerinstances use multi-table inheritance, an entry in badges_badgeinstance is created first before the bannerinstance.

When the bannerinstance is created, it throws an IntegrityError and redirects the user to the default URL. But it does not remove the badgeinstance that was created, which causes errors on the My Banners page when it tries to find the corresponding bannerinstance.

Relevant lines:
https://github.com/mozilla/affiliates/blob/master/apps/banners/views.py#L40
(Assignee)

Updated

6 years ago
Target Milestone: 1.0 → ---
(Assignee)

Updated

6 years ago
Assignee: nobody → mkelly
Status: NEW → ASSIGNED
Target Milestone: --- → 1.0
(Assignee)

Comment 1

6 years ago
Fixed in https://github.com/mozilla/affiliates/commit/9ffc41633aee8eb31ea9285f903e14c0d744ae2d
Status: ASSIGNED → RESOLVED
Last Resolved: 6 years ago
Resolution: --- → FIXED
The bug still seems to exist in its original state, see steps in comment 0. Note cmore and I were able to reproduce this on dev and prod.

Traceback (most recent call last):

 File "/data/www/affiliates.mozilla.org/affiliates-app/vendor/src/django/django/core/handlers/base.py", line 111, in get_response
   response = callback(request, *callback_args, **callback_kwargs)

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/shared/decorators.py", line 11, in decorator
   return view_func(request, *args, **kwargs)

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/views.py", line 73, in my_badges
   {'instance_categories': instance_categories})

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/shared/decorators.py", line 11, in decorator
   return view_func(request, *args, **kwargs)

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/views.py", line 115, in dashboard
   return jingo.render(request, template, context)

 File "/data/www/affiliates.mozilla.org/affiliates-app/vendor/src/jingo/jingo/__init__.py", line 80, in render
   rendered = render_to_string(request, template, context)

 File "/data/www/affiliates.mozilla.org/affiliates-app/vendor/src/jingo/jingo/__init__.py", line 98, in render_to_string
   return template.render(**get_context())

 File "/usr/lib/python2.6/site-packages/jinja2/environment.py", line 891, in render
   return self.environment.handle_exception(exc_info, True)

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/templates/badges/my_badges.html", line 5, in top-level template code
   {% set banner_section = 'current' %}

 File "/data/www/affiliates.mozilla.org/affiliates-app/templates/dashboard.html", line 3, in top-level template code
   {% set user = request.user %}

 File "/data/www/affiliates.mozilla.org/affiliates-app/templates/base.html", line 45, in top-level template code
   {% block content %}{% endblock %}

 File "/data/www/affiliates.mozilla.org/affiliates-app/templates/dashboard.html", line 15, in block "content"
   {% block dashboard_content %}

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/templates/badges/my_badges.html", line 14, in block "dashboard_content"
   {{ macros.dashboard_section(name, instances) }}

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/templates/badges/include/macros.html", line 55, in template
   <div class="col_2">{{ instance.render()|safe }}</div>

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/badges/models.py", line 147, in render
   return self.child().render()

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/banners/models.py", line 99, in render
   'url': self.affiliate_link(),

 File "/data/www/affiliates.mozilla.org/affiliates-app/apps/banners/models.py", line 106, in affiliate_link
   'banner_img_id': self.image.pk})

 File "/data/www/affiliates.mozilla.org/affiliates-app/vendor/src/django/django/db/models/fields/related.py", line 313, in __get__
   rel_obj = rel_mgr.using(db).get(**params)

 File "/data/www/affiliates.mozilla.org/affiliates-app/vendor/src/django/django/db/models/query.py", line 349, in get
   % self.model._meta.object_name)

DoesNotExist: BannerImage matching query does not exist.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
(Assignee)

Comment 3

6 years ago
Fixed in https://github.com/mozilla/affiliates/commit/91ec52f00b10533e810a244d1451fd8300338830

This fix doesn't fix existing broken accounts, but instead fixes the cause. Please verify with a new account.
Status: REOPENED → RESOLVED
Last Resolved: 6 years ago6 years ago
Resolution: --- → FIXED
Sorry mkelly this is still reproducible on dev and prod (bug 695925).
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Bug 696219 will likely solve this. Thx mkelly for digging in your heels to squash this irksome bug.
Depends on: 696219

Comment 6

6 years ago
Passed prod this URL https://affiliates.mozilla.org/link/banner/200/1/1000 and it didn't break my account. The celery restarted resolved the problem.
Status: REOPENED → RESOLVED
Last Resolved: 6 years ago6 years ago
Resolution: --- → FIXED
cmore beat me to the punchline :-) QA verified on prod too.
Status: RESOLVED → VERIFIED
Product: Websites → Firefox Affiliates
Product: Firefox Affiliates → Firefox Affiliates Graveyard
You need to log in before you can comment on or make changes to this bug.