feat: add caching debug logs and configurable max concurrent requests for Komga API to enhance performance monitoring
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
import type { NextRequest} from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
import type { RequestTiming } from "@/lib/services/debug.service";
|
||||
import { DebugService } from "@/lib/services/debug.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { AppError } from "@/utils/errors";
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const logs: RequestTiming[] = await DebugService.getRequestLogs();
|
||||
return NextResponse.json(logs);
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des logs:", error);
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: error.code,
|
||||
name: "Debug fetch error",
|
||||
message: getErrorMessage(error.code),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.DEBUG.FETCH_ERROR,
|
||||
name: "Debug fetch error",
|
||||
message: getErrorMessage(ERROR_CODES.DEBUG.FETCH_ERROR),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const timing: RequestTiming = await request.json();
|
||||
await DebugService.logRequest(timing);
|
||||
return NextResponse.json({
|
||||
message: "✅ Log enregistré avec succès",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de l'enregistrement du log:", error);
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: error.code,
|
||||
name: "Debug save error",
|
||||
message: getErrorMessage(error.code),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.DEBUG.SAVE_ERROR,
|
||||
name: "Debug save error",
|
||||
message: getErrorMessage(ERROR_CODES.DEBUG.SAVE_ERROR),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE() {
|
||||
try {
|
||||
await DebugService.clearLogs();
|
||||
return NextResponse.json({
|
||||
message: "🧹 Logs supprimés avec succès",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la suppression des logs:", error);
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: error.code,
|
||||
name: "Debug clear error",
|
||||
message: getErrorMessage(error.code),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.DEBUG.CLEAR_ERROR,
|
||||
name: "Debug clear error",
|
||||
message: getErrorMessage(ERROR_CODES.DEBUG.CLEAR_ERROR),
|
||||
} as AppError,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,7 @@ export const revalidate = 60;
|
||||
export async function GET() {
|
||||
try {
|
||||
const data = await HomeService.getHomeData();
|
||||
return NextResponse.json(data, {
|
||||
headers: {
|
||||
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
|
||||
}
|
||||
});
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
console.error("API Home - Erreur:", error);
|
||||
if (error instanceof AppError) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BookService } from "@/lib/services/book.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { findHttpStatus } from "@/utils/image-errors";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -18,6 +19,26 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération de la page du livre:", error);
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const { bookId, pageNumber } = await params;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`📷 Page ${pageNumber} not found for book: ${bookId}`);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.IMAGE.FETCH_ERROR,
|
||||
name: "Image not found",
|
||||
message: "Image not found",
|
||||
},
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BookService } from "@/lib/services/book.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { findHttpStatus } from "@/utils/image-errors";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -32,6 +33,27 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération de la miniature de la page:", error);
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const { bookId, pageNumber: pageNumberParam } = await params;
|
||||
const pageNumber: number = parseInt(pageNumberParam);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`📷 Page ${pageNumber} thumbnail not found for book: ${bookId}`);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.IMAGE.FETCH_ERROR,
|
||||
name: "Image not found",
|
||||
message: "Image not found",
|
||||
},
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BookService } from "@/lib/services/book.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { findHttpStatus } from "@/utils/image-errors";
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
@@ -16,6 +17,26 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération de la miniature du livre:", error);
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const bookId: string = (await params).bookId;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`📷 Thumbnail not found for book: ${bookId}`);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.IMAGE.FETCH_ERROR,
|
||||
name: "Image not found",
|
||||
message: "Image not found",
|
||||
},
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import { SeriesService } from "@/lib/services/series.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { findHttpStatus } from "@/utils/image-errors";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -18,6 +19,26 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération de la couverture de la série:", error);
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`📷 First page image not found for series: ${seriesId}`);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.IMAGE.FETCH_ERROR,
|
||||
name: "Image not found",
|
||||
message: "Image not found",
|
||||
},
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import { SeriesService } from "@/lib/services/series.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { findHttpStatus } from "@/utils/image-errors";
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
@@ -15,6 +16,26 @@ export async function GET(
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération de la miniature de la série:", error);
|
||||
|
||||
// Chercher un status HTTP 404 dans la chaîne d'erreurs
|
||||
const httpStatus = findHttpStatus(error);
|
||||
|
||||
if (httpStatus === 404) {
|
||||
const seriesId: string = (await params).seriesId;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`📷 Image not found for series: ${seriesId}`);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: ERROR_CODES.IMAGE.FETCH_ERROR,
|
||||
name: "Image not found",
|
||||
message: "Image not found",
|
||||
},
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Suspense } from "react";
|
||||
import { ClientBookPage } from "@/components/reader/ClientBookPage";
|
||||
import { BookSkeleton } from "@/components/skeletons/BookSkeleton";
|
||||
import { withPageTiming } from "@/lib/hoc/withPageTiming";
|
||||
|
||||
async function BookPage({ params }: { params: { bookId: string } }) {
|
||||
export default async function BookPage({ params }: { params: Promise<{ bookId: string }> }) {
|
||||
const { bookId } = await params;
|
||||
|
||||
return (
|
||||
@@ -12,5 +11,3 @@ async function BookPage({ params }: { params: { bookId: string } }) {
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
export default withPageTiming("BookPage", BookPage);
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { DownloadManager } from "@/components/downloads/DownloadManager";
|
||||
import { withPageTiming } from "@/lib/hoc/withPageTiming";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
function DownloadsPage() {
|
||||
export default function DownloadsPage() {
|
||||
return (
|
||||
<>
|
||||
<DownloadManager />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withPageTiming("DownloadsPage", DownloadsPage);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LoginContent } from "./LoginContent";
|
||||
import { withPageTiming } from "@/lib/hoc/withPageTiming";
|
||||
|
||||
interface PageProps {
|
||||
searchParams: Promise<{
|
||||
@@ -13,7 +12,6 @@ export const metadata: Metadata = {
|
||||
description: "Connectez-vous à votre compte StripStream",
|
||||
};
|
||||
|
||||
async function LoginPage({ searchParams }: PageProps) {
|
||||
export default async function LoginPage({ searchParams }: PageProps) {
|
||||
return <LoginContent searchParams={await searchParams} />;
|
||||
}
|
||||
export default withPageTiming("LoginPage", LoginPage);
|
||||
|
||||
Reference in New Issue
Block a user