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

Duplicate course key error #21

Open
Gehock opened this issue May 7, 2021 · 2 comments
Open

Duplicate course key error #21

Gehock opened this issue May 7, 2021 · 2 comments
Labels

Comments

@Gehock
Copy link
Contributor

Gehock commented May 7, 2021

Attempting to create a duplicate course through LTI generates a HTTP 500 (with debugging disabled) and the attached log (with debugging enabled). Steps to reproduce:

  1. Create a course and a course instance in A+, login to Radar through the course using LTI
  2. Remove the course instance and recreate it with the same name
  3. Attempt to login through LTI again
  4. Radar displays a HTTP 500 during login instead of a more helpful error message

A+ version: v1.8.4-34-g5ffd3b20
Radar version: v3.2-3-gce4e8f1

May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: Internal Server Error: /auth/lti_login
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: Traceback (most recent call last):
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/radar/ltilogin/receivers.py", line 47, in add_course_permissions
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     course = Course.objects.using_namespace(site).get(api_id=course_api_id)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/query.py", line 406, in get
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     raise self.model.DoesNotExist(
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: data.models.Course.DoesNotExist: Course matching query does not exist.
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: During handling of the above exception, another exception occurred:
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: Traceback (most recent call last):
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/aplus_client/django/models.py", line 46, in get_or_create
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return qs.get(api_id=api_obj.id, **kwargs), False
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/query.py", line 406, in get
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     raise self.model.DoesNotExist(
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: data.models.Course.DoesNotExist: Course matching query does not exist.
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: During handling of the above exception, another exception occurred:
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: Traceback (most recent call last):
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return self.cursor.execute(sql, params)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "data_course_key_key"
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: DETAIL:  Key (key)=(minuscsaaltofilaines5testi1) already exists.
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: The above exception was the direct cause of the following exception:
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: Traceback (most recent call last):
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     response = get_response(request)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     response = self.process_exception_by_middleware(e, request)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     response = wrapped_callback(request, *callback_args, **callback_kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return view_func(*args, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/views/decorators/http.py", line 40, in inner
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return func(request, *args, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django_lti_login/views.py", line 80, in lti_login
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     login(request, user)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 132, in login
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     user_logged_in.send(sender=user.__class__, request=request, user=user)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 173, in send
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return [
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 174, in <listcomp>
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     (receiver, receiver(signal=self, sender=sender, **named))
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/radar/ltilogin/receivers.py", line 53, in add_course_permissions
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     course = Course.objects.get_new_or_updated(course_obj, namespace=site, key=course_key)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return getattr(self.get_queryset(), name)(*args, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/aplus_client/django/models.py", line 125, in get_new_or_updated
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return super().get_new_or_updated(api_obj, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/aplus_client/django/models.py", line 34, in get_new_or_updated
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     obj, created = self.get_or_create(api_obj, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/aplus_client/django/models.py", line 48, in get_or_create
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return self.create(api_obj, **kwargs), True
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/aplus_client/django/models.py", line 53, in create
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     obj.save()
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/base.py", line 743, in save
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     self.save_base(using=using, force_insert=force_insert,
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/base.py", line 780, in save_base
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     updated = self._save_table(
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/base.py", line 873, in _save_table
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/base.py", line 910, in _do_insert
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return manager._insert([self], fields=fields, return_id=update_pk,
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return getattr(self.get_queryset(), name)(*args, **kwargs)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/query.py", line 1186, in _insert
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return query.get_compiler(using=using).execute_sql(return_id)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1377, in execute_sql
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     cursor.execute(sql, params)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 99, in execute
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return super().execute(sql, params)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 67, in execute
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return executor(sql, params, many, context)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return self.cursor.execute(sql, params)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/utils.py", line 89, in __exit__
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     raise dj_exc_value.with_traceback(traceback) from exc_value
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:   File "/srv/radar/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]:     return self.cursor.execute(sql, params)
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: django.db.utils.IntegrityError: duplicate key value violates unique constraint "data_course_key_key"
May 07 18:41:02 minus-focal.cs.aalto.fi radar[2924505]: DETAIL:  Key (key)=(minuscsaaltofilaines5testi1) already exists.
@markkuriekkinen
Copy link
Contributor

Interesting. Do you mean that you never deleted a course instance in Radar? When you delete the course instance in A+ and create a new one, the course instance will have a different id in the database. The id is included in some of the LTI parameters and that causes Radar to create a new course in Radar. If the LTI parameters matched an existing course in Radar, Radar would connect to the old course. But as your error shows, Radar can not successfully create the new course if the parameters are not unique compared to other courses

course = Course.objects.using_namespace(site).get(api_id=course_api_id)

https://github.com/apluslms/a-plus/blob/dacf35d7bd4a4212def4f9c298057269f34de720/external_services/lti.py#L77

@Gehock
Copy link
Contributor Author

Gehock commented May 10, 2021

Indeed, I didn't delete the course from Radar beforehand (forgot to do that). To be clear: the only thing that I consider to be a (fairly minor) bug here is the fact that Radar only displays a HTTP 500 to the user and not a more descriptive error message. I wouldn't except Radar to automatically connect the course when the IDs don't match.

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

No branches or pull requests

2 participants