wagtail / wagtail-localize

Translation plugin for Wagtail CMS
https://wagtail-localize.org/
Other
223 stars 85 forks source link

IndexError When Trying to Translate Page #760

Closed auslaner closed 3 months ago

auslaner commented 9 months ago

I am getting the following error when trying to translate a page just after creating a new Locale via the admin interface:

Environment:

Request Method: GET
Request URL: http://chow-whole-hugely.ngrok-free.app/admin/pages/1315/edit/

Django Version: 4.1.10
Python Version: 3.8.13
Installed Applications:
['debug_toolbar',
 'django_rq',
 'axe',
 'concerts',
 'custom_user',
 'events',
 'home',
 'journal',
 'plants',
 'search',
 'shop',
 'wagtail_localize',
 'wagtail_localize.locales',
 'wagtail.contrib.forms',
 'wagtail.contrib.frontend_cache',
 'wagtail.contrib.modeladmin',
 'wagtail.contrib.redirects',
 'wagtail.contrib.routable_page',
 'wagtail.contrib.search_promotions',
 'wagtail.contrib.settings',
 'wagtail.contrib.table_block',
 'wagtail.embeds',
 'wagtail.sites',
 'wagtail.users',
 'wagtail.snippets',
 'wagtail.documents',
 'wagtail.images',
 'wagtail.search',
 'wagtail.admin',
 'wagtail',
 'cas',
 'corsheaders',
 'django_tables2',
 'modelcluster',
 'rest_framework',
 'rest_framework.authtoken',
 'storages',
 'taggit',
 'wagtailaccessibility',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sitemaps',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'wagtail.contrib.redirects.middleware.RedirectMiddleware']

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 56, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/cache.py", line 62, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/wagtail/admin/urls/__init__.py", line 176, in wrapper
    return view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/wagtail/admin/auth.py", line 184, in decorated_view
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/wagtail/admin/views/pages/edit.py", line 354, in dispatch
    response = self.run_hook("before_edit_page", self.request, self.page)
  File "/usr/local/lib/python3.8/site-packages/wagtail/admin/views/generic/mixins.py", line 47, in run_hook
    result = fn(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/wagtail_localize/wagtail_hooks.py", line 277, in before_edit_page
    return edit_translation.edit_translation(request, translation, page)
  File "/usr/local/lib/python3.8/site-packages/wagtail_localize/views/edit_translation.py", line 912, in edit_translation
    "source_translation": [

Exception Type: IndexError at /admin/pages/1315/edit/
Exception Value: list index out of range

My steps to reproduce are:

  1. Create Spanish Locale via wagtail admin synchronized from English
  2. Start rqworker and wait for it to finish
  3. Choose "Translate Page" on one of the created Spanish Pages

Some potentially related oddities I'm seeing are that when creating the Locale, the Django success message says Locale '{0}' created.. Also, from the top level view of the Locales, the newly created Locale will list a usage of 527 pages when the source Locale is 763 Pages.

zerolab commented 9 months ago

Is /admin/pages/1315/edit/ one of the translated pages? The discrepancy between the number of source locale pages and translated pages is "interesting". Do you have anything else in the logs from when the rqworker ran?

If you run this locally with Debug = True, can you expand the error page context around

    "source_translation": [

to see the value of props_translations and perhaps translations?

Also, what Wagtail and wagtail-localize versions are you on?

auslaner commented 9 months ago

Yes, I think it is since it's within the tree hierarchy of the Spanish Locale.

The only notable log lines from the rqworker are two at the beginning:

rq.worker    INFO     default: wagtail_localize.synctree.synchronize_tree(<Locale: English>, <Locale: Spanish>, page_index=None) (bc2de079-6ab1-42c6-ab9c-1779efbf3e4b)
wagtail_localize.synctree WARNING  3 orphaned pages!

Otherwise, it it just a series of page and alias created messages with no other errors or warnings.

props_translations = [{'editUrl': '/admin/pages/161/edit/', 'locale': {'code': 'en', 'displayName': 'English'}, 'title': 'Employment'}]

translations = <PageQuerySet [<GeneralPage: Employment>]>

I am on Wagtail version 5.0.5 and wagtail_localize version 1.7.

zerolab commented 9 months ago

hmm I take it translation.source.locale.language_code is not 'en'.

Can you run the following in the Django shell?

from wagtail.models import Page
from wagtail_localize.models import Translation

page = Page.objects.get(pk=1315)

translation = Translation.objects.get(
    source__object_id=page.translation_key,
    target_locale_id=page.locale_id,
    enabled=True,
)

print(translation.source.locale.language_code)

re: orphaned pages. python manage.py fixtree should take care of that

auslaner commented 9 months ago

Yeah, the above snippet gives me es instead.

zerolab commented 9 months ago

and page.locale.language_code is es too?

I just noticed you said "3. Choose "Translate Page" on one of the created Spanish Pages". Can you record a short screencast of the process with another page, if possible?

auslaner commented 9 months ago

Yes it is!

>>> print(translation.source.locale.language_code)
es
>>> print(page.locale.language_code)
es

https://github.com/wagtail/wagtail-localize/assets/44983332/2615fbc4-5d9b-4e01-93c4-062c18d265e1

auslaner commented 9 months ago

Hmm, could I be causing an issue by having English as en-us in LANGUAGE_CODE = 'en-us' but just en in here:

WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [
    ('en', 'English'),
    ('es', 'Spanish'),
    ('zh', 'Chinese'),
]

Edit: To answer my own question, no, that does not seem to make a difference. I see the same behavior with LANGUAGE_CODE set to en to match the others and confirmed that the language code of the English Locale object was set to en as well.

Nigel2392 commented 9 months ago

I have noticed the Locale '{0}' created too.

This can be fixed by defining success_message as a property function, instead of an attribute on the class - and properly formatting it.

The issue is with the following classes in wagtail_localize.locales.views:

class CreateView(...)
class EditView(...)
class DeleteView(...)
zerolab commented 9 months ago

Let's split the success message to a separate issue - #761

@auslaner it is possible there is an issue with the discrepancy. Will try to test that on a fresh install over the weekend

tomkins commented 7 months ago

This is probably the same as #774 (so #775 should fix it) - although existing data might need to be fixed/removed manually.

zerolab commented 3 months ago

@auslaner can check whether you get the same behaviour with wagtail-localize 1.9?

auslaner commented 3 months ago

It does seem to be solved!

My test is not a perfect recreation of the original issue since I'm now using Django 4.2.13 and wagtail 5.2.5 but I was able to successfully install wagtail-localize 1.9, create a locale, and then translate a page from that locale without hitting any errors so I'd say this issue is safe to close!