diff --git a/apps/promotions/views_application.py b/apps/promotions/views_application.py index 89da921..becd075 100644 --- a/apps/promotions/views_application.py +++ b/apps/promotions/views_application.py @@ -2,6 +2,7 @@ from drf_spectacular.utils import extend_schema from rest_framework import mixins, status from rest_framework.decorators import action from rest_framework import exceptions +from rest_framework.exceptions import NotFound from rest_framework.generics import CreateAPIView, get_object_or_404, RetrieveAPIView, ListAPIView from rest_framework.response import Response from rest_framework.settings import api_settings @@ -15,6 +16,7 @@ from .models import Plan, Promotion, EventSaver from .serializers import PlanSerializer, PromotionSerializer, EventSerializer, PromoteSerializer, UserPlanSerializer from .tasks import analyze_event_task from ..users.models import User +from django.utils.translation import gettext as _ class ApplicationUserPlanViewSet( @@ -42,7 +44,10 @@ class ApplicationUserPlanViewSet( if not user: user_info = get_user_info(user_uuid) if user_info: - user, created = User.objects.update_or_create(uuid=user_uuid) + user, created = User.objects.get_or_create(uuid=user_uuid) + + if not user: + raise NotFound(_('user {user_uuid} not found').format(user_uuid=user_uuid)) self.request.user = user # return Promotion.objects.filter(application=application) diff --git a/utils/exceptions.py b/utils/exceptions.py index 807f9b5..27f7b07 100644 --- a/utils/exceptions.py +++ b/utils/exceptions.py @@ -1,5 +1,7 @@ import logging +from django.conf import settings +from django.utils import timezone from rest_framework.exceptions import APIException from rest_framework.views import exception_handler as drf_exception_handler @@ -12,17 +14,36 @@ def exception_handler(exc, context): response = drf_exception_handler(exc, context) if response is not None: - # ساختار دلخواه خود را تعریف می‌کنیم response_data = { 'success': False, 'status_code': response.status_code, - 'message': 'An error occurred', - 'details': {} + 'status_message': str(getattr(exc, 'default_detail', exc)), + 'details': getattr(exc, 'detail', None), } if isinstance(exc, APIException): - response_data['message'] = exc.detail if isinstance(exc.detail, str) else "Validation error" - response_data['details'] = exc.detail if isinstance(exc.detail, dict) else {} + try: + error = getattr(getattr(exc, 'detail', None), 'code', None) or getattr(exc, 'code', None) + if not error: + error = getattr(exc, 'default_code') + except: + error = '' + + # if isinstance(exc.detail, str): + # message = exc.detail + # elif isinstance(exc.detail, dict): + # if 'message' in exc.detail or 'string' in exc.detail: + # message = exc.detail.get('message') or exc.detail.get('string') + # else: + # message = error + # + # else: + # message = error + # + # response_data['message'] = message + response_data['details'] = {"message": exc.detail} + response_data['details']['error'] = error + response_data['details']['timestamp'] = timezone.now().isoformat() response.data = response_data @@ -47,16 +68,36 @@ class ErrorMiddleware: { "success": False, "status_code": 500, - "message": "Internal server error", - "details": str(exception) # فقط در حالت توسعه! در تولید بهتر است لاگ شود. + "status_message": "Internal server error", + "details": str(exception) if settings.DEBUG else None, }, status=500 ) from rest_framework.exceptions import APIException +from rest_framework import status +from django.utils.translation import gettext_lazy as _ + class UnprocessableEntity(APIException): status_code = 422 default_detail = 'The request was well-formed but cannot be processed due to semantic errors.' default_code = 'unprocessable_entity' + + +class ServiceUnavailable(APIException): + status_code = status.HTTP_503_SERVICE_UNAVAILABLE + default_ = _('SERVICE_UNAVAILABLE') + default_code = 'service_unavailable' + default_detail = 'Service Unavailable' + + +class Conflict(APIException): + status_code = status.HTTP_409_CONFLICT + default_ = _('CONFLICT') + default_code = 'conflict' + default_detail = 'Conflict' + + +# class NotFound(APIException):