from rest_framework.exceptions import APIException from rest_framework import status from rest_framework.views import exception_handler as drf_exception_handler from rest_framework.response import Response from rest_framework.exceptions import ValidationError def error_response(error_code, message, details=None, status_code=status.HTTP_400_BAD_REQUEST): # print(f'>>>> {error_code}') response_data = { "status": "error", "code": error_code, "message": message, "details": details or {} } return Response(response_data, status=status_code) def exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. response = drf_exception_handler(exc, context) # قالب‌بندی جدید خطاها formatted_errors = [] if response is not None: # تعیین نوع خطاها print(f'>>> {type(exc)}/ {exc}') if isinstance(exc, ValidationError): error_code = "validation_error" message = "There were validation errors." if isinstance(response.data, list): for error in response.data: formatted_errors.append({ "field": None, # No specific field when the error is a list "message": error }) else: # فرمت کردن خطاها به فرمت جدید print(f'>>>>>> {response.data}') for field, errors in response.data.items(): if isinstance(errors, list): for error in errors: # print() # print(f'>>>> {field}') formatted_errors.append({ "field": field, "message": error }) else: formatted_errors.append({ "field": field, "message": errors }) seen_fields = set() for i in range(len(formatted_errors) - 1, -1, -1): field = formatted_errors[i]['field'] if field in seen_fields: # اگر فیلد تکراری بود، آن را حذف کن del formatted_errors[i] else: # اولین باری که فیلد دیده شده، آن را ثبت کن seen_fields.add(field) elif isinstance(exc, AppAPIException): error_code = "app_api_error" message = "An error occurred while processing the request." for field, errors in response.data.items(): if isinstance(errors, list): for error in errors: formatted_errors.append({ "message": error }) else: formatted_errors.append({ "message": errors }) else: error_code = "server_error" message = "An error occurred." # فرمت کردن خطاها به فرمت جدید for field, errors in response.data.items(): if isinstance(errors, list): for error in errors: formatted_errors.append({ "message": error }) else: formatted_errors.append({ "message": errors }) # تنظیم ساختار جدید برای پاسخ خطا response.data = { "status": "error", "code": error_code, "status_code": response.status_code, # Adding the status code "message": message, "errors": formatted_errors } return response class AppAPIException(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = 'An error occurred while processing the request.' def __init__(self, detail=None, status_code=None): if detail is None: detail = self.default_detail if status_code is None: status_code = self.default_code else: self.status_code = status_code super().__init__(detail, status_code) class ExpiredCodeException(APIException): status_code = status.HTTP_410_GONE default_detail = "The verification code has expired." default_code = "expired_code" class UserNotFoundException(APIException): status_code = status.HTTP_404_NOT_FOUND default_detail = 'user notfound' class NotFoundException(APIException): status_code = status.HTTP_404_NOT_FOUND default_detail = "The requested resource was not found." default_code = "not_found" class InvaliedCodeVrify(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = "code notfound" class ServiceUnavailableException(APIException): status_code = status.HTTP_500_INTERNAL_SERVER_ERROR default_detail = 'Service temporarily unavailable' default_code = 'service_unavailable'