Skip to content
This repository has been archived by the owner on Jan 21, 2025. It is now read-only.

IntegrityError on Application actions when CharacterOwnership doesn't exist #1

Open
marnvermuldir opened this issue Jun 1, 2023 · 1 comment

Comments

@marnvermuldir
Copy link
Contributor

Bug Description

Any action that generates an AA notification will raise an unhandled IntegrityError exception when the applicant character doesn't have a CharacterOwnership record.

Steps to Reproduce

Steps to reproduce the behavior:

  1. Open an app for a character without a CharacterOwnership record
  2. Click on Accept
  3. Click Yes on Confirmation Page
  4. See error

Expected behavior

No exception is generated and both a AA notification is sent to the applicant and an EVE Mail window is popped up in the reviewing Officer's game client.

Screenshots

N/A

Please complete the following information:

  • 0.1.8
  • 3.4.0
  • N/A

Additional context

Error Context

Environment:


Request Method: POST
Request URL: http://auth.eveuniversity.org/sad/action/reject/3632

Django Version: 4.0.10
Python Version: 3.9.15
Installed Applications:
['allianceauth',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'django_celery_beat',
 'bootstrapform',
 'sortedm2m',
 'esi',
 'allianceauth.authentication',
 'allianceauth.services',
 'allianceauth.eveonline',
 'allianceauth.groupmanagement',
 'allianceauth.notifications',
 'allianceauth.thirdparty.navhelper',
 'allianceauth.analytics',
 'eunicore',
 'allianceauth.services.modules.discord',
 'allianceauth.services.modules.mumble',
 'allianceauth.services.modules.phpbb3',
 'aasrp',
 'allianceauth.corputils',
 'blacklist',
 'buybackprogram',
 'eveuniverse',
 'fleetpings',
 'freight',
 'groupassign',
 'memberaudit',
 'memberaudit_securegroups',
 'moonstuff',
 'securegroups',
 'structures',
 'structuretimers',
 'taskmonitor',
 'package_monitor',
 'afat',
 'opcalendar',
 'fittings',
 'membertools']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'allianceauth.authentication.middleware.UserSettingsMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'allianceauth.analytics.middleware.AnalyticsMiddleware']


Traceback (most recent call last):
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 75, in execute
    return self.cursor.execute(query, args)
  File "/opt/venv/lib/python3.9/site-packages/MySQLdb/cursors.py", line 206, in execute
    res = self._query(query)
  File "/opt/venv/lib/python3.9/site-packages/MySQLdb/cursors.py", line 319, in _query
    db.query(q)
  File "/opt/venv/lib/python3.9/site-packages/MySQLdb/connections.py", line 254, in query
    _mysql.connection.query(self, query)

During handling of the above exception ((1048, "Column 'user_id' cannot be null")), another exception occurred:
  File "/opt/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 56, in inner
    response = get_response(request)
  File "/opt/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/allianceauth/authentication/decorators.py", line 35, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/esi/decorators.py", line 81, in _wrapped_view
    return view_func(request, tokens, *args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/membertools/views.py", line 1350, in hr_admin_reject_action
    notify(
  File "/opt/venv/lib/python3.9/site-packages/allianceauth/notifications/core.py", line 5, in __call__
    return self._add_notification(*args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/allianceauth/notifications/core.py", line 28, in _add_notification
    Notification.objects.notify_user(
  File "/opt/venv/lib/python3.9/site-packages/allianceauth/notifications/managers.py", line 48, in notify_user
    obj = self.create(user=user, title=title, message=message, level=level)
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/query.py", line 514, in create
    obj.save(force_insert=True, using=self.db)
  File "/opt/venv/lib/python3.9/site-packages/allianceauth/notifications/models.py", line 66, in save
    super().save(*args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/base.py", line 806, in save
    self.save_base(
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/base.py", line 857, in save_base
    updated = self._save_table(
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/base.py", line 1000, in _save_table
    results = self._do_insert(
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/base.py", line 1041, in _do_insert
    return manager._insert(
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/query.py", line 1434, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/opt/venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1621, in execute_sql
    cursor.execute(sql, params)
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 102, in execute
    return super().execute(sql, params)
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/opt/venv/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 80, in execute
    raise IntegrityError(*tuple(e.args))

Exception Type: IntegrityError at /sad/action/reject/3632
Exception Value: (1048, "Column 'user_id' cannot be null")
@marnvermuldir
Copy link
Contributor Author

The exception is caused by Application.user property depending solely on CharacterOwnership to determine a character to user mapping.

All user properties need to be updated to try first the CharacterOwnership record if it exists, and fall back the first OwnershipRecord for the character if it exists. Otherwise, return None.

All properties that need a user but don't access it through the object's user property should be updated to use the user property to cut down on code duplication.

Add Unit Tests where needed to cover cases where CharacterOwnership doesn't exist but OwnershipRecord does, and when neither exist.

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

No branches or pull requests

1 participant