Closed Bug 1493137 Opened 6 years ago Closed 6 years ago

[translate] Prevent duplicate translation submissions

Categories

(Webtools Graveyard :: Pontoon, defect, P2)

defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: mathjazz, Assigned: mathjazz)

Details

Attachments

(1 file)

Since launching the Translation.active flag, about once per day we see an IntegrityError caused by the violation of the partial unique contraint on entity-locale-plural_form-active.

It happens because we don't prevent duplicate translation submissions properly.

Steps to reproduce:

1. Open a string without any translations.
2. Disable Translate Toolkit Checks.
3. Write a translation into the editor and submit it with pressing the Enter key twice (instantly once press after another).

Expected result: Translation gets saved.

Actual result: Translation gets saved, but the message says "Oops, something went wrong." and when you try to leave the string, you get the Unsaved changes warning. The 2nd submission fails with the following error:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "/app/pontoon/base/utils.py", line 285, in wrap
    return f(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 185, in inner
    return func(*args, **kwargs)
  File "/app/pontoon/base/views.py", line 684, in update_translation
    t.save()
  File "/app/pontoon/base/models.py", line 2726, in save
    super(Translation, self).save(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 808, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 838, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 924, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 963, in _do_insert
    using=using, raw=raw)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1112, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
IntegrityError: duplicate key value violates unique constraint "base_transl_entity__ed9592_partial"
DETAIL:  Key (entity_id, locale_id, active)=(189094, 205, t) already exists.
Note: poor duplicate translation submission prevention also allows users to submit two identical approved translations. To do that, you need to repeat the steps mentioned in Comment #1 for a string that already has an existing translation.
Commit pushed to master at https://github.com/mozilla/pontoon

https://github.com/mozilla/pontoon/commit/ebd342922d04df2dfbbce23ac5a15ee1e71d50fe
Fix bug 1493137: Prevent duplicate translation submissions (#1086)
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Product: Webtools → Webtools Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: