"""A single response shape for every error the API returns. {"detail": "...", "code": "...", "errors": {"field": ["..."]}} `errors` is only present for validation failures. The SPA reads `code` to branch (e.g. `registration_required`) and `detail` to show a message. """ from rest_framework import exceptions from rest_framework.views import exception_handler as drf_exception_handler def exception_handler(exc, context): response = drf_exception_handler(exc, context) if response is None: return None code = getattr(exc, "default_code", "error") data = response.data if isinstance(exc, exceptions.ValidationError): detail = "The submitted data was invalid." if isinstance(data, dict): non_field = data.get("detail") or data.get("non_field_errors") if non_field: detail = non_field[0] if isinstance(non_field, list) else str(non_field) response.data = {"detail": str(detail), "code": code, "errors": data} return response detail = data.get("detail") if isinstance(data, dict) else data response.data = {"detail": str(detail), "code": code} return response