Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding exercises to sets seems to be broken on latest version when attributes are missing. #1269

Closed
RemcoSchrijver opened this issue Mar 8, 2023 · 10 comments

Comments

@RemcoSchrijver
Copy link
Contributor

Steps to Reproduce

Try to add an exercise to a set, it seems the exercise seems to be missing the ENGLISH_SHORT_NAME attribute, then it proceeds to crash and throws a 500 error. I already synced all exercises from upstream to make sure all attributes are there, but I think the attribute error should either be caught our fail more gracefully.

Expected results:
Be able to browse all exercises and select them.
Actual results:
Returned a 500 error.

Logs
Internal Server Error: /en/workout/set/day/13/set/add
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/wger/src/wger/manager/views/set.py", line 126, in create
    return render(request, 'set/add.html', context)
  File "/usr/local/lib/python3.10/dist-packages/django/shortcuts.py", line 24, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/usr/local/lib/python3.10/dist-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/usr/local/lib/python3.10/dist-packages/django/template/backends/django.py", line 62, in render
    return self.template.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 175, in render
    return self._render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1064, in render
    output = self.filter_expression.resolve(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 742, in resolve
    new_obj = func(obj, *arg_vals)
  File "/usr/local/lib/python3.10/dist-packages/crispy_forms/templatetags/crispy_forms_filters.py", line 122, in as_crispy_field
    return template.render(c)
  File "/usr/local/lib/python3.10/dist-packages/django/template/backends/django.py", line 62, in render
    return self.template.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 175, in render
    return self._render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/usr/local/lib/python3.10/dist-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/dist-packages/crispy_forms/templatetags/crispy_forms_field.py", line 130, in render
    return str(field)
  File "/usr/local/lib/python3.10/dist-packages/django/utils/html.py", line 419, in <lambda>
    klass.__str__ = lambda self: mark_safe(klass_str(self))
  File "/usr/local/lib/python3.10/dist-packages/django/forms/boundfield.py", line 34, in __str__
    return self.as_widget()
  File "/usr/local/lib/python3.10/dist-packages/django/forms/boundfield.py", line 99, in as_widget
    return widget.render(
  File "/home/wger/src/wger/utils/widgets.py", line 123, in render
    options = self.render_options(choices, value)
  File "/home/wger/src/wger/utils/widgets.py", line 134, in render_options
    for option_value, option_label in chain(self.choices, choices):
  File "/usr/local/lib/python3.10/dist-packages/django/forms/models.py", line 1410, in __iter__
    yield self.choice(obj)
  File "/usr/local/lib/python3.10/dist-packages/django/forms/models.py", line 1424, in choice
    self.field.label_from_instance(obj),
  File "/usr/local/lib/python3.10/dist-packages/django/forms/models.py", line 1510, in label_from_instance
    return str(obj)
  File "/home/wger/src/wger/exercises/models/base.py", line 125, in __str__
    return f"base {self.uuid} ({self.get_exercise(ENGLISH_SHORT_NAME).name})"
AttributeError: 'NoneType' object has no attribute 'name'
@rolandgeider
Copy link
Member

Hi! Yes you are right. Did you add any exercise on your instance or just synced them?

@RemcoSchrijver
Copy link
Contributor Author

I do indeed have a couple exercises I added myself, so I suspect that those are indeed breaking things.

@rolandgeider
Copy link
Member

That's probably it, it was previously not really clear what language an added exercise had. I'll remove the ENGLISH_SHORT_NAME parameter so that this doesn't crash

@rolandgeider
Copy link
Member

mhhh, if english is not available it should return the first available translation. Can you run docker compose exec web python3 manage.py exercises-health-check. It'll show if there are any exercises without any translations

@RemcoSchrijver
Copy link
Contributor Author

Yes running that command gives me the following output:

manage.py exercises-health-check output
Exercise base b955b629-5c57-4f98-b200-e96e138c300f has no English translation!
Exercise base 5f8370d9-aa89-4dcc-9d97-d9da86a2f183 has no English translation!
Exercise base 5b14e0f0-1131-4ad9-9821-5703f1370bc5 has no English translation!
Exercise base 27d322ba-cbf5-44fa-a3bc-1999c6711757 has no English translation!
Exercise base 8953df3e-4027-45fb-8740-5d9bea55dde1 has no English translation!
Exercise base 4a7052cc-6abb-4e24-bcff-6f9b13d550f1 has no English translation!
Exercise base d103baeb-7fec-40f0-b1ac-bb1bf10fdb6c has no English translation!
Exercise base 722a07f0-dea0-43bf-a2bf-0c50920849ba has no English translation!
Exercise base c3502b66-98db-4177-8061-745df0ce1239 has no English translation!
Exercise base 6a496c73-721d-4ed2-9f7f-337e8ad2b388 has no translations!
Exercise base dd320a0c-3442-452c-a007-1c84e11533aa has no English translation!
Exercise base 8f7b6fce-4a75-42fc-b217-efe44e349fdc has no English translation!
Exercise base e878ecf3-fbb2-4f0e-a546-9769c7ff3241 has no English translation!
Exercise base b117f605-3b74-488f-bb03-4f434c8d529f has no English translation!
Exercise base 31f51ab6-94a6-436f-9d41-632d85b7e01f has no English translation!
Exercise base 515cb39c-fead-4b59-a4ba-a10c5b0b8c84 has no English translation!
Exercise base 82d2e843-7fbf-443e-ba49-c71923adeb83 has no English translation!
Exercise base 9094b15d-7d98-4393-bcc1-9eb60d3d7941 has no English translation!
Exercise base f8434123-3c86-44e2-b596-dc7f9bf22d7b has no English translation!
Exercise base 09dd3e3c-e53a-4e2c-a2e3-645d334f53e2 has duplicate translations for language IDs: [2]!
Language 2:
  * Assisted Dips (uuid: 22879094-ced4-4bd1-81f2-76fdfeb867e6 )
  * Dips (uuid: 7191e015-0c60-4376-9be0-733b9754b7f8 )

Exercise base e3ee06c8-3c06-4af1-881f-1ab6ab105627 has no English translation!
Exercise base 201edd07-93f8-474b-8db0-e13e5283ee2b has no English translation!
Exercise base f2d7abc4-81e4-4f17-befa-86389cc1aab0 has no English translation!
Exercise base b7b690a7-2e65-40f9-a9cb-e61501a72fed has no English translation!
Exercise base 115ecb25-27bc-40a2-9618-00e8572af3c8 has no English translation!
Exercise base 9e694c44-2462-430d-8108-6982fd681ade has no English translation!
Exercise base 6c86a314-bf0e-4b31-aea7-40891fa5288a has no English translation!
Exercise base 306187ff-d8b0-4d6f-8ecd-bf9818fdf6b5 has no English translation!
Exercise base c29884c8-a4fd-4491-8bfd-2dac88aa7184 has no English translation!
Exercise base c323d8a4-310f-4381-925c-3893ef5f8422 has no English translation!
Exercise base 058945bb-7fa8-4724-95fb-51ee8df20929 has no translations!
Exercise base 4ceb1ba5-1ce1-4fe3-b60a-5d0e173a2ab3 has no English translation!
Exercise base 425180b6-0523-4cb5-bb6a-3d477ad887f2 has no English translation!
Exercise base a70ccc73-bc04-4af5-9bb4-dbd5b24deea9 has no translations!
Exercise base e13f19be-a3bd-4ed3-8915-176ea5bc7893 has no English translation!
Exercise base e5c5fd36-4092-4bdd-9457-9c14bd87c258 has no English translation!
Exercise base 62d7ebaf-2c44-405b-878f-506ac2523fa7 has no English translation!
Exercise base 51e6e4f6-ce59-4137-b7af-3dd4c8874eee has no English translation!
Exercise base fc8a493e-e659-4dcc-ada1-8855d83cb07a has no English translation!
Exercise base b54be6ca-384c-4013-80cc-1eaf73a5e382 has no English translation!
Exercise base 284b74bb-ca6b-45be-902d-ed6179094ea1 has no English translation!
Exercise base 92ee2003-8659-4c21-8627-12c766e19a84 has no English translation!
Exercise base 73405d63-a539-486e-996e-1e72572fbe5d has no English translation!
Exercise base 5bea7603-d90b-4c0a-9d07-2345cb4fa60f has no English translation!
Exercise base 713ee452-2775-4a68-8a7c-f1d22b5cd469 has no English translation!
Exercise base f242c9e5-14ea-414a-aad5-4c53971143e9 has no English translation!
Exercise base 6c45c38c-15cb-425b-b1f6-d8dd38e028f2 has no English translation!
Exercise base b16e3e5d-8401-4d2b-919c-15b536f9ec5e has no English translation!
Exercise base a68c991c-ac42-47c8-9a84-9b288a4a7a76 has no English translation!
Exercise base 719e97ef-a813-4c46-88f5-934466e37dae has no English translation!
Exercise base 43508fc9-743d-4597-8202-7ba507313bff has no English translation!
Exercise base a3af48da-7722-4d6c-92d5-ef0db510f551 has no English translation!
Exercise base 9ae8772d-570c-4d16-abd4-34f5d5081e4e has no English translation!
Exercise base d91e446a-8bca-45ad-9b59-2e301ac25af8 has no English translation!
Exercise base 69dda766-aab8-4ad4-942e-9ad252ca12fd has no English translation!
Exercise base 625f15b7-0f02-4ede-9558-64f964aebbc2 has no English translation!
Exercise base 24b62fb4-0158-486e-89f1-9a5f1db234ef has no English translation!
Exercise base 557ae429-100d-4d5b-a173-e5186fa2d9bc has no English translation!
Exercise base 85542e68-ce96-42ae-9c2a-f5b28daf5985 has no English translation!
Exercise base c5d822d4-8fa9-4968-9ed3-c86645917111 has no English translation!
Exercise base d1ebb9e8-ba7c-43ea-ac52-27f09adf8fec has no English translation!
Exercise base b5413941-a9a4-4c9c-9b4a-0cfbb450e9d7 has no English translation!
Exercise base f04e9890-e157-44f5-a7a3-0ce1b5cb7c3f has no English translation!
Exercise base 6dd693a5-b593-4cb6-ac48-13fc6017b9cf has no English translation!
Exercise base 51348a59-c291-492d-8a93-c166944c4745 has no English translation!
Exercise base c4fa778b-3bdd-42f9-8d2c-9e4a43e3b187 has no English translation!
Exercise base 8a25b161-cb71-46a3-8765-fa8630029727 has no English translation!
Exercise base 5912d7ed-6a0e-4b4c-b30a-fc9f3f890fc1 has no English translation!
Exercise base 275fb49f-975c-4d6e-9d63-2c86ed740f40 has no English translation!
Exercise base 52dec48d-25a4-4a78-b66b-ad6a773e143a has no English translation!
Exercise base 53906cd1-61f1-4d56-ac60-e4fcc5824861 has no English translation!
Exercise base 57e17672-52b9-43cf-8d0d-4b3f06a0c0d0 has no English translation!

@rolandgeider
Copy link
Member

yeah, those without any translations are definitely the problem, the other ones shouldn't cause any problems. I'm not sure how they could have been created in the first place, perhaps we should add some checks that prevent the server from starting? In any case you can just delete those (and wait till the cache clears):

docker compose exec --user postgres db psql --user wger

DELETE FROM exercises_exercise WHERE uuid = '6a496c73-721d-4ed2-9f7f-337e8ad2b388';
DELETE FROM exercises_exercise WHERE uuid = '058945bb-7fa8-4724-95fb-51ee8df20929';
DELETE FROM exercises_exercise WHERE uuid = 'a70ccc73-bc04-4af5-9bb4-dbd5b24deea9';

I also don't think this is the cause of your other issue, after all you get a name in the autocompleter (a "base" is just the base data for an exercise such as category, muscles, images, etc., the translations are only the language specific things such as name or description)

@RemcoSchrijver
Copy link
Contributor Author

Yeah at the moment I couldn't access the exercise list either in the workout selector because of the missing translations. But maybe a better way would be to just not show these exercises to the end user? And maybe give some feedback to the admin users by flagging them for missing fields?

As for the origin, I think this might have happened because of a failed migration to the new format?

@rolandgeider
Copy link
Member

did you manage to get this running again?

@rolandgeider
Copy link
Member

This will be handled in #1319, closing here

@ranasats
Copy link

I actually just ran into this error using the docker-compose example. My linked issue is here:

wger-project/docker#72

I'm on the latest wger build, wger/server:latest on docker, so should that already have the above fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants