[WEB-4281] chore: error code on project updation endpoint (#7218)
This commit is contained in:
parent
9523c28c3e
commit
ec0ef98c1b
4 changed files with 295 additions and 259 deletions
|
|
@ -24,55 +24,51 @@ class ProjectSerializer(BaseSerializer):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
read_only_fields = ["workspace", "deleted_at"]
|
read_only_fields = ["workspace", "deleted_at"]
|
||||||
|
|
||||||
|
def validate_name(self, name):
|
||||||
|
project_id = self.instance.id if self.instance else None
|
||||||
|
workspace_id = self.context["workspace_id"]
|
||||||
|
|
||||||
|
project = Project.objects.filter(name=name, workspace_id=workspace_id)
|
||||||
|
|
||||||
|
if project_id:
|
||||||
|
project = project.exclude(id=project_id)
|
||||||
|
|
||||||
|
if project.exists():
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
detail="PROJECT_NAME_ALREADY_EXIST",
|
||||||
|
)
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
def validate_identifier(self, identifier):
|
||||||
|
project_id = self.instance.id if self.instance else None
|
||||||
|
workspace_id = self.context["workspace_id"]
|
||||||
|
|
||||||
|
project = Project.objects.filter(
|
||||||
|
identifier=identifier, workspace_id=workspace_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if project_id:
|
||||||
|
project = project.exclude(id=project_id)
|
||||||
|
|
||||||
|
if project.exists():
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
detail="PROJECT_IDENTIFIER_ALREADY_EXIST",
|
||||||
|
)
|
||||||
|
|
||||||
|
return identifier
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
identifier = validated_data.get("identifier", "").strip().upper()
|
workspace_id = self.context["workspace_id"]
|
||||||
if identifier == "":
|
|
||||||
raise serializers.ValidationError(detail="Project Identifier is required")
|
|
||||||
|
|
||||||
if ProjectIdentifier.objects.filter(
|
project = Project.objects.create(**validated_data, workspace_id=workspace_id)
|
||||||
name=identifier, workspace_id=self.context["workspace_id"]
|
|
||||||
).exists():
|
ProjectIdentifier.objects.create(
|
||||||
raise serializers.ValidationError(detail="Project Identifier is taken")
|
name=project.identifier, project=project, workspace_id=workspace_id
|
||||||
project = Project.objects.create(
|
|
||||||
**validated_data, workspace_id=self.context["workspace_id"]
|
|
||||||
)
|
|
||||||
_ = ProjectIdentifier.objects.create(
|
|
||||||
name=project.identifier,
|
|
||||||
project=project,
|
|
||||||
workspace_id=self.context["workspace_id"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return project
|
return project
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
|
||||||
identifier = validated_data.get("identifier", "").strip().upper()
|
|
||||||
|
|
||||||
# If identifier is not passed update the project and return
|
|
||||||
if identifier == "":
|
|
||||||
project = super().update(instance, validated_data)
|
|
||||||
return project
|
|
||||||
|
|
||||||
# If no Project Identifier is found create it
|
|
||||||
project_identifier = ProjectIdentifier.objects.filter(
|
|
||||||
name=identifier, workspace_id=instance.workspace_id
|
|
||||||
).first()
|
|
||||||
if project_identifier is None:
|
|
||||||
project = super().update(instance, validated_data)
|
|
||||||
project_identifier = ProjectIdentifier.objects.filter(
|
|
||||||
project=project
|
|
||||||
).first()
|
|
||||||
if project_identifier is not None:
|
|
||||||
project_identifier.name = identifier
|
|
||||||
project_identifier.save()
|
|
||||||
return project
|
|
||||||
# If found check if the project_id to be updated and identifier project id is same
|
|
||||||
if project_identifier.project_id == instance.id:
|
|
||||||
# If same pass update
|
|
||||||
project = super().update(instance, validated_data)
|
|
||||||
return project
|
|
||||||
|
|
||||||
# If not same fail update
|
|
||||||
raise serializers.ValidationError(detail="Project Identifier is already taken")
|
|
||||||
|
|
||||||
|
|
||||||
class ProjectLiteSerializer(BaseSerializer):
|
class ProjectLiteSerializer(BaseSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -239,205 +239,165 @@ class ProjectViewSet(BaseViewSet):
|
||||||
|
|
||||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER], level="WORKSPACE")
|
@allow_permission([ROLE.ADMIN, ROLE.MEMBER], level="WORKSPACE")
|
||||||
def create(self, request, slug):
|
def create(self, request, slug):
|
||||||
try:
|
workspace = Workspace.objects.get(slug=slug)
|
||||||
workspace = Workspace.objects.get(slug=slug)
|
|
||||||
|
|
||||||
serializer = ProjectSerializer(
|
serializer = ProjectSerializer(
|
||||||
data={**request.data}, context={"workspace_id": workspace.id}
|
data={**request.data}, context={"workspace_id": workspace.id}
|
||||||
|
)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
|
||||||
|
# Add the user as Administrator to the project
|
||||||
|
_ = ProjectMember.objects.create(
|
||||||
|
project_id=serializer.data["id"], member=request.user, role=20
|
||||||
|
)
|
||||||
|
# Also create the issue property for the user
|
||||||
|
_ = IssueUserProperty.objects.create(
|
||||||
|
project_id=serializer.data["id"], user=request.user
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
|
|
||||||
# Add the user as Administrator to the project
|
if serializer.data["project_lead"] is not None and str(
|
||||||
_ = ProjectMember.objects.create(
|
serializer.data["project_lead"]
|
||||||
project_id=serializer.data["id"], member=request.user, role=20
|
) != str(request.user.id):
|
||||||
|
ProjectMember.objects.create(
|
||||||
|
project_id=serializer.data["id"],
|
||||||
|
member_id=serializer.data["project_lead"],
|
||||||
|
role=20,
|
||||||
)
|
)
|
||||||
# Also create the issue property for the user
|
# Also create the issue property for the user
|
||||||
_ = IssueUserProperty.objects.create(
|
IssueUserProperty.objects.create(
|
||||||
project_id=serializer.data["id"], user=request.user
|
project_id=serializer.data["id"],
|
||||||
|
user_id=serializer.data["project_lead"],
|
||||||
)
|
)
|
||||||
|
|
||||||
if serializer.data["project_lead"] is not None and str(
|
# Default states
|
||||||
serializer.data["project_lead"]
|
states = [
|
||||||
) != str(request.user.id):
|
|
||||||
ProjectMember.objects.create(
|
|
||||||
project_id=serializer.data["id"],
|
|
||||||
member_id=serializer.data["project_lead"],
|
|
||||||
role=20,
|
|
||||||
)
|
|
||||||
# Also create the issue property for the user
|
|
||||||
IssueUserProperty.objects.create(
|
|
||||||
project_id=serializer.data["id"],
|
|
||||||
user_id=serializer.data["project_lead"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Default states
|
|
||||||
states = [
|
|
||||||
{
|
|
||||||
"name": "Backlog",
|
|
||||||
"color": "#60646C",
|
|
||||||
"sequence": 15000,
|
|
||||||
"group": "backlog",
|
|
||||||
"default": True,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Todo",
|
|
||||||
"color": "#60646C",
|
|
||||||
"sequence": 25000,
|
|
||||||
"group": "unstarted",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "In Progress",
|
|
||||||
"color": "#F59E0B",
|
|
||||||
"sequence": 35000,
|
|
||||||
"group": "started",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Done",
|
|
||||||
"color": "#46A758",
|
|
||||||
"sequence": 45000,
|
|
||||||
"group": "completed",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Cancelled",
|
|
||||||
"color": "#9AA4BC",
|
|
||||||
"sequence": 55000,
|
|
||||||
"group": "cancelled",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
State.objects.bulk_create(
|
|
||||||
[
|
|
||||||
State(
|
|
||||||
name=state["name"],
|
|
||||||
color=state["color"],
|
|
||||||
project=serializer.instance,
|
|
||||||
sequence=state["sequence"],
|
|
||||||
workspace=serializer.instance.workspace,
|
|
||||||
group=state["group"],
|
|
||||||
default=state.get("default", False),
|
|
||||||
created_by=request.user,
|
|
||||||
)
|
|
||||||
for state in states
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
project = self.get_queryset().filter(pk=serializer.data["id"]).first()
|
|
||||||
|
|
||||||
# Create the model activity
|
|
||||||
model_activity.delay(
|
|
||||||
model_name="project",
|
|
||||||
model_id=str(project.id),
|
|
||||||
requested_data=request.data,
|
|
||||||
current_instance=None,
|
|
||||||
actor_id=request.user.id,
|
|
||||||
slug=slug,
|
|
||||||
origin=base_host(request=request, is_app=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
serializer = ProjectListSerializer(project)
|
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
except IntegrityError as e:
|
|
||||||
if "already exists" in str(e):
|
|
||||||
return Response(
|
|
||||||
{
|
|
||||||
"name": "The project name is already taken",
|
|
||||||
"code": "PROJECT_NAME_ALREADY_EXIST",
|
|
||||||
},
|
|
||||||
status=status.HTTP_409_CONFLICT,
|
|
||||||
)
|
|
||||||
except Workspace.DoesNotExist:
|
|
||||||
return Response(
|
|
||||||
{"error": "Workspace does not exist"}, status=status.HTTP_404_NOT_FOUND
|
|
||||||
)
|
|
||||||
except serializers.ValidationError:
|
|
||||||
return Response(
|
|
||||||
{
|
{
|
||||||
"identifier": "The project identifier is already taken",
|
"name": "Backlog",
|
||||||
"code": "PROJECT_IDENTIFIER_ALREADY_EXIST",
|
"color": "#60646C",
|
||||||
|
"sequence": 15000,
|
||||||
|
"group": "backlog",
|
||||||
|
"default": True,
|
||||||
},
|
},
|
||||||
status=status.HTTP_409_CONFLICT,
|
{
|
||||||
|
"name": "Todo",
|
||||||
|
"color": "#60646C",
|
||||||
|
"sequence": 25000,
|
||||||
|
"group": "unstarted",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "In Progress",
|
||||||
|
"color": "#F59E0B",
|
||||||
|
"sequence": 35000,
|
||||||
|
"group": "started",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Done",
|
||||||
|
"color": "#46A758",
|
||||||
|
"sequence": 45000,
|
||||||
|
"group": "completed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cancelled",
|
||||||
|
"color": "#9AA4BC",
|
||||||
|
"sequence": 55000,
|
||||||
|
"group": "cancelled",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
State.objects.bulk_create(
|
||||||
|
[
|
||||||
|
State(
|
||||||
|
name=state["name"],
|
||||||
|
color=state["color"],
|
||||||
|
project=serializer.instance,
|
||||||
|
sequence=state["sequence"],
|
||||||
|
workspace=serializer.instance.workspace,
|
||||||
|
group=state["group"],
|
||||||
|
default=state.get("default", False),
|
||||||
|
created_by=request.user,
|
||||||
|
)
|
||||||
|
for state in states
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
project = self.get_queryset().filter(pk=serializer.data["id"]).first()
|
||||||
|
|
||||||
|
# Create the model activity
|
||||||
|
model_activity.delay(
|
||||||
|
model_name="project",
|
||||||
|
model_id=str(project.id),
|
||||||
|
requested_data=request.data,
|
||||||
|
current_instance=None,
|
||||||
|
actor_id=request.user.id,
|
||||||
|
slug=slug,
|
||||||
|
origin=base_host(request=request, is_app=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
serializer = ProjectListSerializer(project)
|
||||||
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
def partial_update(self, request, slug, pk=None):
|
def partial_update(self, request, slug, pk=None):
|
||||||
try:
|
# try:
|
||||||
if not ProjectMember.objects.filter(
|
if not ProjectMember.objects.filter(
|
||||||
member=request.user,
|
member=request.user,
|
||||||
workspace__slug=slug,
|
workspace__slug=slug,
|
||||||
project_id=pk,
|
project_id=pk,
|
||||||
role=20,
|
role=20,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
).exists():
|
).exists():
|
||||||
return Response(
|
|
||||||
{"error": "You don't have the required permissions."},
|
|
||||||
status=status.HTTP_403_FORBIDDEN,
|
|
||||||
)
|
|
||||||
|
|
||||||
workspace = Workspace.objects.get(slug=slug)
|
|
||||||
|
|
||||||
project = Project.objects.get(pk=pk)
|
|
||||||
intake_view = request.data.get("inbox_view", project.intake_view)
|
|
||||||
current_instance = json.dumps(
|
|
||||||
ProjectSerializer(project).data, cls=DjangoJSONEncoder
|
|
||||||
)
|
|
||||||
if project.archived_at:
|
|
||||||
return Response(
|
|
||||||
{"error": "Archived projects cannot be updated"},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
|
||||||
)
|
|
||||||
|
|
||||||
serializer = ProjectSerializer(
|
|
||||||
project,
|
|
||||||
data={**request.data, "intake_view": intake_view},
|
|
||||||
context={"workspace_id": workspace.id},
|
|
||||||
partial=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
if intake_view:
|
|
||||||
intake = Intake.objects.filter(
|
|
||||||
project=project, is_default=True
|
|
||||||
).first()
|
|
||||||
if not intake:
|
|
||||||
Intake.objects.create(
|
|
||||||
name=f"{project.name} Intake",
|
|
||||||
project=project,
|
|
||||||
is_default=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
project = self.get_queryset().filter(pk=serializer.data["id"]).first()
|
|
||||||
|
|
||||||
model_activity.delay(
|
|
||||||
model_name="project",
|
|
||||||
model_id=str(project.id),
|
|
||||||
requested_data=request.data,
|
|
||||||
current_instance=current_instance,
|
|
||||||
actor_id=request.user.id,
|
|
||||||
slug=slug,
|
|
||||||
origin=base_host(request=request, is_app=True),
|
|
||||||
)
|
|
||||||
serializer = ProjectListSerializer(project)
|
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
except IntegrityError as e:
|
|
||||||
if "already exists" in str(e):
|
|
||||||
return Response(
|
|
||||||
{"name": "The project name is already taken"},
|
|
||||||
status=status.HTTP_409_CONFLICT,
|
|
||||||
)
|
|
||||||
except (Project.DoesNotExist, Workspace.DoesNotExist):
|
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "Project does not exist"}, status=status.HTTP_404_NOT_FOUND
|
{"error": "You don't have the required permissions."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
)
|
)
|
||||||
except serializers.ValidationError:
|
|
||||||
|
workspace = Workspace.objects.get(slug=slug)
|
||||||
|
|
||||||
|
project = Project.objects.get(pk=pk)
|
||||||
|
intake_view = request.data.get("inbox_view", project.intake_view)
|
||||||
|
current_instance = json.dumps(
|
||||||
|
ProjectSerializer(project).data, cls=DjangoJSONEncoder
|
||||||
|
)
|
||||||
|
if project.archived_at:
|
||||||
return Response(
|
return Response(
|
||||||
{"identifier": "The project identifier is already taken"},
|
{"error": "Archived projects cannot be updated"},
|
||||||
status=status.HTTP_409_CONFLICT,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
serializer = ProjectSerializer(
|
||||||
|
project,
|
||||||
|
data={**request.data, "intake_view": intake_view},
|
||||||
|
context={"workspace_id": workspace.id},
|
||||||
|
partial=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
if intake_view:
|
||||||
|
intake = Intake.objects.filter(project=project, is_default=True).first()
|
||||||
|
if not intake:
|
||||||
|
Intake.objects.create(
|
||||||
|
name=f"{project.name} Intake",
|
||||||
|
project=project,
|
||||||
|
is_default=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
project = self.get_queryset().filter(pk=serializer.data["id"]).first()
|
||||||
|
|
||||||
|
model_activity.delay(
|
||||||
|
model_name="project",
|
||||||
|
model_id=str(project.id),
|
||||||
|
requested_data=request.data,
|
||||||
|
current_instance=current_instance,
|
||||||
|
actor_id=request.user.id,
|
||||||
|
slug=slug,
|
||||||
|
origin=base_host(request=request, is_app=True),
|
||||||
|
)
|
||||||
|
serializer = ProjectListSerializer(project)
|
||||||
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
def destroy(self, request, slug, pk):
|
def destroy(self, request, slug, pk):
|
||||||
if (
|
if (
|
||||||
WorkspaceMember.objects.filter(
|
WorkspaceMember.objects.filter(
|
||||||
|
|
|
||||||
|
|
@ -88,31 +88,63 @@ export const CreateProjectForm: FC<TCreateProjectFormProps> = observer((props) =
|
||||||
handleNextStep(res.id);
|
handleNextStep(res.id);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
captureError({
|
try {
|
||||||
eventName: PROJECT_TRACKER_EVENTS.create,
|
captureError({
|
||||||
payload: {
|
eventName: PROJECT_TRACKER_EVENTS.create,
|
||||||
identifier: formData.identifier,
|
payload: {
|
||||||
},
|
identifier: formData.identifier,
|
||||||
});
|
},
|
||||||
if (err?.data.code === "PROJECT_NAME_ALREADY_EXIST") {
|
|
||||||
setToast({
|
|
||||||
type: TOAST_TYPE.ERROR,
|
|
||||||
title: t("toast.error"),
|
|
||||||
message: t("project_name_already_taken"),
|
|
||||||
});
|
});
|
||||||
} else if (err?.data.code === "PROJECT_IDENTIFIER_ALREADY_EXIST") {
|
|
||||||
setToast({
|
// Handle the new error format where codes are nested in arrays under field names
|
||||||
type: TOAST_TYPE.ERROR,
|
const errorData = err?.data ?? {};
|
||||||
title: t("toast.error"),
|
|
||||||
message: t("project_identifier_already_taken"),
|
// Check for specific error codes in the new format
|
||||||
});
|
if (errorData.name?.includes("PROJECT_NAME_ALREADY_EXIST")) {
|
||||||
} else {
|
|
||||||
Object.keys(err?.data ?? {}).map((key) => {
|
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: t("error"),
|
title: t("toast.error"),
|
||||||
message: err.data[key],
|
message: t("project_name_already_taken"),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorData?.identifier?.includes("PROJECT_IDENTIFIER_ALREADY_EXIST")) {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("toast.error"),
|
||||||
|
message: t("project_identifier_already_taken"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle other field-specific errors (excluding name and identifier which are handled above)
|
||||||
|
Object.keys(errorData).forEach((field) => {
|
||||||
|
// Skip name and identifier fields as they're handled separately above
|
||||||
|
if (field === "name" || field === "identifier") return;
|
||||||
|
|
||||||
|
const fieldErrors = errorData[field];
|
||||||
|
if (Array.isArray(fieldErrors)) {
|
||||||
|
fieldErrors.forEach((errorMessage) => {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("error"),
|
||||||
|
message: errorMessage,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (typeof fieldErrors === "string") {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("error"),
|
||||||
|
message: fieldErrors,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Fallback error handling if the error processing fails
|
||||||
|
console.error("Error processing API error:", error);
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("toast.error"),
|
||||||
|
message: t("something_went_wrong"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -104,18 +104,66 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
|
||||||
message: t("project_settings.general.toast.success"),
|
message: t("project_settings.general.toast.success"),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((err) => {
|
||||||
captureError({
|
try {
|
||||||
eventName: PROJECT_TRACKER_EVENTS.update,
|
captureError({
|
||||||
payload: {
|
eventName: PROJECT_TRACKER_EVENTS.update,
|
||||||
id: projectId,
|
payload: {
|
||||||
},
|
id: projectId,
|
||||||
});
|
},
|
||||||
setToast({
|
});
|
||||||
type: TOAST_TYPE.ERROR,
|
|
||||||
title: t("toast.error"),
|
// Handle the new error format where codes are nested in arrays under field names
|
||||||
message: error?.error ?? t("project_settings.general.toast.error"),
|
const errorData = err ?? {};
|
||||||
});
|
|
||||||
|
// Check for specific error codes in the new format
|
||||||
|
if (errorData.name?.includes("PROJECT_NAME_ALREADY_EXIST")) {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("toast.error"),
|
||||||
|
message: t("project_name_already_taken"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorData?.identifier?.includes("PROJECT_IDENTIFIER_ALREADY_EXIST")) {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("toast.error"),
|
||||||
|
message: t("project_identifier_already_taken"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle other field-specific errors (excluding name and identifier which are handled above)
|
||||||
|
Object.keys(errorData).forEach((field) => {
|
||||||
|
// Skip name and identifier fields as they're handled separately above
|
||||||
|
if (field === "name" || field === "identifier") return;
|
||||||
|
|
||||||
|
const fieldErrors = errorData[field];
|
||||||
|
if (Array.isArray(fieldErrors)) {
|
||||||
|
fieldErrors.forEach((errorMessage) => {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("error"),
|
||||||
|
message: errorMessage,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (typeof fieldErrors === "string") {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("error"),
|
||||||
|
message: fieldErrors,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Fallback error handling if the error processing fails
|
||||||
|
console.error("Error processing API error:", error);
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("toast.error"),
|
||||||
|
message: t("something_went_wrong"),
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue