feat: Implement centralized error capture and handling with new middleware, services, and API endpoints, and add new admin and statistics API views.

This commit is contained in:
pacnpal
2026-01-02 15:55:42 -05:00
parent 1adba1b804
commit 95700c7d7b
43 changed files with 2477 additions and 158 deletions

View File

@@ -20,6 +20,7 @@ from drf_spectacular.utils import (
from rest_framework import serializers
from apps.accounts.models import PasswordReset
from apps.core.utils import capture_and_log
UserModel = get_user_model()
@@ -64,6 +65,7 @@ class UserOutputSerializer(serializers.ModelSerializer):
avatar_url = serializers.SerializerMethodField()
display_name = serializers.SerializerMethodField()
role = serializers.SerializerMethodField()
class Meta:
model = UserModel
@@ -74,9 +76,12 @@ class UserOutputSerializer(serializers.ModelSerializer):
"display_name",
"date_joined",
"is_active",
"is_staff",
"is_superuser",
"role",
"avatar_url",
]
read_only_fields = ["id", "date_joined", "is_active"]
read_only_fields = ["id", "date_joined", "is_active", "is_staff", "is_superuser", "role"]
def get_display_name(self, obj):
"""Get the user's display name."""
@@ -89,6 +94,15 @@ class UserOutputSerializer(serializers.ModelSerializer):
return obj.profile.get_avatar_url()
return None
@extend_schema_field(serializers.CharField())
def get_role(self, obj) -> str:
"""Compute effective role based on permissions."""
if obj.is_superuser:
return "SUPERUSER"
if obj.is_staff:
return "ADMIN"
return "USER"
class LoginInputSerializer(serializers.Serializer):
"""Input serializer for user login."""
@@ -235,8 +249,8 @@ The ThrillWiki Team
logger.info(f"Verification email sent successfully to {user.email}. No email ID in response.")
except Exception as e:
# Log the error but don't fail registration
logger.error(f"Failed to send verification email to {user.email}: {e}")
# Capture error but don't fail registration
capture_and_log(e, f'Send verification email to {user.email}', source='api', severity='low')
class SignupOutputSerializer(serializers.Serializer):

View File

@@ -21,6 +21,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from apps.accounts.services.social_provider_service import SocialProviderService
from apps.core.utils import capture_and_log
# Import directly from the auth serializers.py file (not the serializers package)
from .serializers import (
@@ -188,7 +189,7 @@ class LoginAPIView(APIView):
"access": str(access_token),
"refresh": str(refresh),
"user": user,
"detail": "Login successful",
"message": "Login successful",
}
)
return Response(response_serializer.data)
@@ -820,10 +821,7 @@ The ThrillWiki Team
return Response({"detail": "Verification email sent successfully", "success": True})
except Exception as e:
import logging
logger = logging.getLogger(__name__)
logger.error(f"Failed to send verification email to {user.email}: {e}")
capture_and_log(e, 'Send verification email', source='api')
return Response(
{"detail": "Failed to send verification email"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR