From 4c4ef82a78cd0febb43b10627711626b38814edc Mon Sep 17 00:00:00 2001
From: magicfelix <felix@felix-zauberer.de>
Date: Fri, 14 Feb 2025 16:07:34 +0100
Subject: [PATCH] Raise GraphQL errors instead of causing 500

---
 .../paweljong/schema/event_registration.py    | 81 ++++++++++---------
 1 file changed, 44 insertions(+), 37 deletions(-)

diff --git a/aleksis/apps/paweljong/schema/event_registration.py b/aleksis/apps/paweljong/schema/event_registration.py
index b617a2a..87d5ff5 100644
--- a/aleksis/apps/paweljong/schema/event_registration.py
+++ b/aleksis/apps/paweljong/schema/event_registration.py
@@ -1,4 +1,4 @@
-from django.db import transaction
+from django.db import transaction, IntegrityError
 from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django.utils.text import slugify
@@ -54,40 +54,52 @@ class SendEventRegistrationMutation(graphene.Mutation):
 
     @transaction.atomic
     def mutate(self, info, event: graphene.ID, event_registration: EventRegistrationInputType, **kwargs):
-        event = Event.objects.get(pk=event)
+        if not event_registration["retraction_consent"]:
+            raise ValidationError(_("Retraction consent is required"))
 
-        print(event_registration)
+        event = Event.objects.get(pk=event)
 
         email = None
 
         if event_registration["email"] is not None:
-            _mail_address = MailAddress.objects.create(
-                local_part=event_registration["email"]["local_part"],
-                domain=event_registration["email"]["domain"],
-            )
+            try:
+                _mail_address = MailAddress.objects.create(
+                    local_part=event_registration["email"]["local_part"],
+                    domain=event_registration["email"]["domain"],
+                )
+            except IntegrityError:
+                raise ValidationError(_("Mail address already in use."))
+
             email = str(_mail_address)
         elif event_registration["user"] is not None:
             email = event_registration["user"]["email"]
 
         # Create user
-        if event_registration is not None:
-            user = User.objects.create(
-                username=event_registration["user"]["username"],
-                email=event_registration["user"]["email"],
-            )
+        if event_registration["user"] is not None:
+            try:
+                user = User.objects.create(
+                    username=event_registration["user"]["username"],
+                    email=event_registration["user"]["email"],
+                )
+            except IntegrityError:
+                raise ValidationError(_("A user with this username or e-mail already exists."))
+
             user.set_password(event_registration["user"]["password"])
             user.save()
         else:
             user = self.request.user
 
-        person, created = Person.objects.get_or_create(
-            user=user,
-            defaults={
-                "email": email,
-                "first_name": event_registration["person"]["first_name"],
-                "last_name": event_registration["person"]["last_name"],
-            },
-        )
+        try:
+            person, created = Person.objects.get_or_create(
+                user=user,
+                defaults={
+                    "email": email,
+                    "first_name": event_registration["person"]["first_name"],
+                    "last_name": event_registration["person"]["last_name"],
+                },
+            )
+        except IntegrityError:
+            raise ValidationError(_("A person with using the e-mail address %s already exists." % email))
 
         # Store contact information in database
         for field_name in ["date_of_birth", "sex", "address", "mobile_number"]:
@@ -101,23 +113,22 @@ class SendEventRegistrationMutation(graphene.Mutation):
 
         if event_registration["person"] is not None:
             for guardian_data in event_registration["person"]["guardians"]:
-                guardian, created = Person.objects.get_or_create(
-                    defaults={
-                        "mobile_number": guardian_data["mobile_number"],
-                    },
-                    first_name=guardian_data["first_name"],
-                    last_name=guardian_data["last_name"],
-                    email=guardian_data["email"],
-                )
+                try:
+                    guardian, created = Person.objects.get_or_create(
+                        defaults={
+                            "mobile_number": guardian_data["mobile_number"],
+                        },
+                        first_name=guardian_data["first_name"],
+                        last_name=guardian_data["last_name"],
+                        email=guardian_data["email"],
+                    )
+                except IntegrityError:
+                    raise ValidationError(_("A person with using the e-mail address %s already exists." % guardian_data["email"]))
 
                 person.guardians.add(guardian)
             person.save()
 
         if event_registration["email"] is not None:
-            _mail_address = MailAddress.objects.create(
-                local_part=event_registration["email"]["local_part"],
-                domain=event_registration["email"]["domain"],
-            )
             _mail_address.person = person
             _mail_address.save()
 
@@ -194,8 +205,4 @@ class SendEventRegistrationMutation(graphene.Mutation):
             user=person,
         )
 
-        if event_registration["retraction_consent"]:
-            return SendEventRegistrationMutation(ok=True)
-
-        raise ValidationError(_("Retraction consent is required"))
-        return SendEventRegistrationMutation(ok=False)
+        return SendEventRegistrationMutation(ok=True)
-- 
GitLab