fix: Implementasi retry mechanism dan error handling untuk database connections Deskripsi: Menambahkan withRetry wrapper pada berbagai API routes untuk menangani transient database errors dan meningkatkan reliabilitas koneksi Memperbaiki error handling pada notification, authentication, dan user validation endpoints dengan response 503 untuk database connection errors Update prisma.ts dengan konfigurasi logging yang lebih baik dan datasources configuration Menambahkan validasi input parameters pada beberapa endpoints Update dokumentasi QWEN.md dengan commit message format dan comment standards Update .env.example dengan connection pool settings yang lebih lengkap File yang diubah: src/lib/prisma.ts — Konfigurasi Prisma client & logging src/app/api/admin/notifikasi/count/route.tsx src/app/api/auth/mobile-login/route.ts src/app/api/mobile/notification/[id]/route.ts src/app/api/user-validate/route.ts Dan 27 file API routes lainnya (penerapan withRetry secara konsisten) QWEN.md — Dokumentasi commit & comment standards .env.example — Database connection pool configuration ### No Issue
128 lines
3.2 KiB
TypeScript
128 lines
3.2 KiB
TypeScript
import { decrypt } from "@/app/(auth)/_lib/decrypt";
|
|
import { withRetry } from "@/lib/prisma-retry";
|
|
import { prisma } from "@/lib";
|
|
import { cookies } from "next/headers";
|
|
import { NextResponse } from "next/server";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export async function GET(req: Request) {
|
|
try {
|
|
const SESSIONKEY = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!;
|
|
const TOKENKEY = process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!;
|
|
const cookieStore = cookies();
|
|
|
|
const authHeader = req.headers.get("Authorization") || "";
|
|
const bearerToken = authHeader.startsWith("Bearer ")
|
|
? authHeader.split(" ")[1]
|
|
: undefined;
|
|
|
|
const token = cookieStore.get(SESSIONKEY)?.value || bearerToken;
|
|
|
|
if (!token) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "Unauthorized token not found",
|
|
},
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
const decrypted = await decrypt({
|
|
token,
|
|
encodedKey: TOKENKEY,
|
|
});
|
|
|
|
if (!decrypted?.id) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "Unauthorized: invalid token data",
|
|
},
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
const user = await withRetry(
|
|
() =>
|
|
prisma.user.findUnique({
|
|
where: {
|
|
id: decrypted.id,
|
|
},
|
|
}),
|
|
undefined,
|
|
"validateUser"
|
|
);
|
|
|
|
if (!user) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "User tidak ditemukan",
|
|
},
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
if (!user.active) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "User belum aktif",
|
|
data: user,
|
|
},
|
|
{ status: 403 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: "Berhasil mendapatkan data",
|
|
data: user,
|
|
});
|
|
} catch (error) {
|
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
const errorStack = error instanceof Error ? error.stack : "No stack";
|
|
|
|
// Log detailed error for debugging
|
|
console.error("❌ [USER-VALIDATE] Error:", errorMsg);
|
|
console.error("❌ [USER-VALIDATE] Stack:", errorStack);
|
|
console.error("❌ [USER-VALIDATE] Time:", new Date().toISOString());
|
|
|
|
// Check if it's a database connection error
|
|
if (
|
|
errorMsg.includes("Prisma") ||
|
|
errorMsg.includes("database") ||
|
|
errorMsg.includes("connection")
|
|
) {
|
|
console.error(
|
|
"❌ [USER-VALIDATE] Database connection error detected!"
|
|
);
|
|
console.error(
|
|
"❌ [USER-VALIDATE] DATABASE_URL exists:",
|
|
!!process.env.DATABASE_URL
|
|
);
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "Database connection error. Please try again.",
|
|
error: process.env.NODE_ENV === "development" ? errorMsg : "Internal server error",
|
|
},
|
|
{ status: 503 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: "Terjadi kesalahan pada server",
|
|
error:
|
|
process.env.NODE_ENV === "development" ? errorMsg : "Internal server error",
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|