Skip to content

Commit

Permalink
Register: Show info-message on IntegrityError
Browse files Browse the repository at this point in the history
In rare cases, it seems to be possible to submit multiple register forms
in parallel. In some cases the form validation can succeed, but the
insertion in the databse (via `register_user`) will fail with an exception.

Instead of showing a plain server-error, a message is now displayed to the
user.

example stack trace:
```
UniqueViolation: duplicate key value violates unique constraint "portal_user_email_key"
DETAIL:  Key (email)=([email protected]) already exists.

  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

IntegrityError: duplicate key value violates unique constraint "portal_user_email_key"
DETAIL:  Key (email)=([email protected]) already exists.

  File "django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "inyoka/utils/http.py", line 39, in proxy
    rv = f(request, *args, **kwargs)
  File "inyoka/portal/views.py", line 248, in register
    user = User.objects.register_user(
  File "inyoka/portal/user.py", line 228, in register_user
    user = self.create_user(username, email, password)
  File "inyoka/portal/user.py", line 206, in create_user
    user.save()
  File "inyoka/portal/user.py", line 316, in save
    super().save(*args, **kwargs)
  File "django/contrib/auth/base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "django/db/models/base.py", line 739, in save
    self.save_base(using=using, force_insert=force_insert,
  File "django/db/models/base.py", line 776, in save_base
    updated = self._save_table(
  File "django/db/models/base.py", line 881, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "django/db/models/base.py", line 919, in _do_insert
    return manager._insert(
  File "django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "django/db/models/query.py", line 1270, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "django/db/models/sql/compiler.py", line 1416, in execute_sql
    cursor.execute(sql, params)
  File "django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
```
  • Loading branch information
chris34 committed Feb 8, 2024
1 parent 1c9df69 commit 4919d27
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions inyoka/portal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from datetime import date, datetime, timedelta
from django.contrib.messages.views import SuccessMessageMixin
from django.db import IntegrityError
from icalendar import Calendar as iCal, Event as iEvent
from time import time

Expand Down Expand Up @@ -245,17 +246,23 @@ def register(request):
form.captcha_solution = request.session.get('captcha_solution')
if form.is_valid():
data = form.cleaned_data
user = User.objects.register_user(
username=data['username'],
email=data['email'],
password=data['password'])

messages.success(request,
_('The username “%(username)s” was successfully registered. '
'An email with the activation key was sent to '
'“%(email)s”.') % {
'username': escape(user.username),
'email': escape(user.email)})
try:
user = User.objects.register_user(
username=data['username'],
email=data['email'],
password=data['password'])
except IntegrityError:
messages.info(request,
_('Please check whether you received an email with the activation key. If not, try '
'to register with another user name or email-address.'))
else:
messages.success(request,
_('The username “%(username)s” was successfully registered. '
'An email with the activation key was sent to '
'“%(email)s”.') % {
'username': escape(user.username),
'email': escape(user.email)})

# clean up request.session
request.session.pop('captcha_solution', None)
Expand Down

0 comments on commit 4919d27

Please sign in to comment.