From 17730a05e04b4f1ff117062eea06a24947cde353 Mon Sep 17 00:00:00 2001 From: ManuMar28 Date: Wed, 5 Aug 2026 14:26:02 -0300 Subject: [PATCH 1/2] fix: handle soft-delete errors in UI and disable caching for apps list --- .../[id]/environments/[envId]/route.ts | 11 ++-- app/api/applications/[id]/route.ts | 11 ++-- app/api/applications/route.ts | 2 + .../applications/[id]/settings/page.tsx | 52 +++++++++++++++++-- app/dashboard/applications/page.tsx | 36 ++++++++++--- lib/api.ts | 1 + next-env.d.ts | 2 +- 7 files changed, 96 insertions(+), 19 deletions(-) diff --git a/app/api/applications/[id]/environments/[envId]/route.ts b/app/api/applications/[id]/environments/[envId]/route.ts index a99de80..ac90831 100644 --- a/app/api/applications/[id]/environments/[envId]/route.ts +++ b/app/api/applications/[id]/environments/[envId]/route.ts @@ -73,10 +73,13 @@ export async function DELETE( if (!response.ok) { const errorText = await response.text(); - return NextResponse.json( - { error: errorText || "Failed to delete environment" }, - { status: response.status } - ); + let errorData; + try { + errorData = JSON.parse(errorText); + } catch (e) { + errorData = { error: errorText || "Failed to delete environment" }; + } + return NextResponse.json(errorData, { status: response.status }); } return new NextResponse(null, { status: 204 }); diff --git a/app/api/applications/[id]/route.ts b/app/api/applications/[id]/route.ts index 77f3490..fc19e20 100644 --- a/app/api/applications/[id]/route.ts +++ b/app/api/applications/[id]/route.ts @@ -70,10 +70,13 @@ export async function DELETE( if (!response.ok) { const errorText = await response.text(); - return NextResponse.json( - { error: errorText || "Failed to delete application" }, - { status: response.status } - ); + let errorData; + try { + errorData = JSON.parse(errorText); + } catch (e) { + errorData = { error: errorText || "Failed to delete application" }; + } + return NextResponse.json(errorData, { status: response.status }); } return new NextResponse(null, { status: 204 }); diff --git a/app/api/applications/route.ts b/app/api/applications/route.ts index 1977eff..5d4715a 100644 --- a/app/api/applications/route.ts +++ b/app/api/applications/route.ts @@ -1,6 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { fetchBackend } from "@/lib/api"; +export const dynamic = "force-dynamic"; + export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url); diff --git a/app/dashboard/applications/[id]/settings/page.tsx b/app/dashboard/applications/[id]/settings/page.tsx index 6b1be27..92efea4 100644 --- a/app/dashboard/applications/[id]/settings/page.tsx +++ b/app/dashboard/applications/[id]/settings/page.tsx @@ -38,6 +38,7 @@ export default function ApplicationSettingsPage({ const [isLoading, setIsLoading] = useState(true) const [isSaving, setIsSaving] = useState(false) const [deleteDialogOpen, setDeleteDialogOpen] = useState(false) + const [deleteAppError, setDeleteAppError] = useState<{ message: string, details?: string[] } | null>(null) const [formData, setFormData] = useState({ name: "", description: "", @@ -53,6 +54,7 @@ export default function ApplicationSettingsPage({ const [isSavingEnv, setIsSavingEnv] = useState(false) const [confirmDeleteEnvOpen, setConfirmDeleteEnvOpen] = useState(false) const [selectedEnvForDelete, setSelectedEnvForDelete] = useState(null) + const [deleteEnvError, setDeleteEnvError] = useState<{ message: string, details?: string[] } | null>(null) useEffect(() => { const fetchAppAndEnvs = async () => { @@ -200,6 +202,7 @@ export default function ApplicationSettingsPage({ const handleDeleteEnvConfirm = async () => { if (!selectedEnvForDelete) return setIsSavingEnv(true) + setDeleteEnvError(null) try { const res = await fetch(`/api/applications/${id}/environments/${selectedEnvForDelete.id}`, { method: "DELETE", @@ -209,10 +212,15 @@ export default function ApplicationSettingsPage({ setConfirmDeleteEnvOpen(false) setSelectedEnvForDelete(null) } else { - console.error("Failed to delete environment") + const errData = await res.json().catch(() => ({ message: "Error al eliminar el ambiente" })) + setDeleteEnvError({ + message: errData.message || errData.error || "Error al eliminar el ambiente", + details: errData.details + }) } } catch (error) { console.error("Error deleting environment:", error) + setDeleteEnvError({ message: "Ocurrió un error inesperado al eliminar el ambiente" }) } finally { setIsSavingEnv(false) } @@ -242,6 +250,7 @@ export default function ApplicationSettingsPage({ const handleDelete = async () => { setIsSaving(true) + setDeleteAppError(null) try { const response = await fetch(`/api/applications/${id}`, { method: "DELETE", @@ -249,10 +258,15 @@ export default function ApplicationSettingsPage({ if (response.ok) { router.push("/dashboard/applications") } else { - console.error("Failed to delete application") + const errData = await response.json().catch(() => ({ message: "Error al eliminar la aplicación" })) + setDeleteAppError({ + message: errData.message || errData.error || "Error al eliminar la aplicación", + details: errData.details + }) } } catch (error) { console.error("Error deleting application:", error) + setDeleteAppError({ message: "Ocurrió un error inesperado al eliminar la aplicación" }) } finally { setIsSaving(false) } @@ -467,7 +481,10 @@ export default function ApplicationSettingsPage({ {/* Delete Dialog */} - + { + setDeleteDialogOpen(open) + if (!open) setDeleteAppError(null) + }}> Eliminar Aplicación @@ -480,6 +497,18 @@ export default function ApplicationSettingsPage({ Esta acción no se puede deshacer. + {deleteAppError && ( +
+
{deleteAppError.message}
+ {deleteAppError.details && deleteAppError.details.length > 0 && ( +
    + {deleteAppError.details.map((detail, idx) => ( +
  • {detail}
  • + ))} +
+ )} +
+ )} @@ -616,7 +622,10 @@ export default function ApplicationSettingsPage({