From 50221b451c205c1bfa406025a5e1460d9818f1c8 Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Thu, 24 Oct 2024 15:14:16 +0800 Subject: [PATCH] refactor: route and server fetch --- app/api/detail/route.ts | 47 ++++++------- app/api/monitor/route.ts | 49 ++++++------- app/api/server/route.ts | 38 +++-------- lib/serverFetch.tsx | 144 +++++++++++++++++++++------------------ 4 files changed, 130 insertions(+), 148 deletions(-) diff --git a/app/api/detail/route.ts b/app/api/detail/route.ts index 80264c3..eddf954 100644 --- a/app/api/detail/route.ts +++ b/app/api/detail/route.ts @@ -7,12 +7,6 @@ import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; -interface NezhaDataResponse extends NezhaAPISafe { - error?: string; - cause?: string; - code?: string; -} - export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { redirect("/"); @@ -20,32 +14,31 @@ export const GET = auth(async function GET(req) { const { searchParams } = new URL(req.url); const server_id = searchParams.get("server_id"); + if (!server_id) { return NextResponse.json( { error: "server_id is required" }, { status: 400 }, ); } - const response = (await GetServerDetail({ - server_id: parseInt(server_id), - })) as NezhaDataResponse; - if (response.error) { - console.log(response.error); - return NextResponse.json({ error: response.error }, { status: 400 }); + + try { + const serverIdNum = parseInt(server_id, 10); + if (isNaN(serverIdNum)) { + return NextResponse.json( + { error: "server_id must be a valid number" }, + { status: 400 }, + ); + } + + const detailData = await GetServerDetail({ server_id: serverIdNum }); + return NextResponse.json(detailData, { status: 200 }); + } catch (error) { + console.error("Error in GET handler:", error); + // @ts-ignore + const statusCode = error.statusCode || 500; + // @ts-ignore + const message = error.message || "Internal Server Error"; + return NextResponse.json({ error: message }, { status: statusCode }); } - if (response.cause) { - console.log("GetServerDetail error(cause):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - if (response.code === "ConnectionRefused") { - console.log("GetServerDetail error(code):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - return NextResponse.json(response, { status: 200 }); }); diff --git a/app/api/monitor/route.ts b/app/api/monitor/route.ts index a3b34f1..5a8f204 100644 --- a/app/api/monitor/route.ts +++ b/app/api/monitor/route.ts @@ -1,4 +1,3 @@ -import { ServerMonitorChart } from "@/app/[locale]/types/nezha-api"; import { auth } from "@/auth"; import getEnv from "@/lib/env-entry"; import { GetServerMonitor } from "@/lib/serverFetch"; @@ -7,12 +6,6 @@ import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; -interface NezhaDataResponse { - error?: string; - cause?: string; - code?: string; -} - export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { redirect("/"); @@ -26,26 +19,26 @@ export const GET = auth(async function GET(req) { { status: 400 }, ); } - const response = (await GetServerMonitor({ - server_id: parseInt(server_id), - })) as NezhaDataResponse; - if (response.error) { - console.log(response.error); - return NextResponse.json({ error: response.error }, { status: 400 }); + + try { + const serverIdNum = parseInt(server_id, 10); + if (isNaN(serverIdNum)) { + return NextResponse.json( + { error: "server_id must be a number" }, + { status: 400 }, + ); + } + + const monitorData = await GetServerMonitor({ + server_id: serverIdNum, + }); + return NextResponse.json(monitorData, { status: 200 }); + } catch (error) { + console.error("Error in GET handler:", error); + // @ts-ignore + const statusCode = error.statusCode || 500; + // @ts-ignore + const message = error.message || "Internal Server Error"; + return NextResponse.json({ error: message }, { status: statusCode }); } - if (response.cause) { - console.log("GetServerMonitor error(cause):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - if (response.code === "ConnectionRefused") { - console.log("GetServerMonitor error(code):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - return NextResponse.json(response, { status: 200 }); }); diff --git a/app/api/server/route.ts b/app/api/server/route.ts index bdd48be..ddfa7da 100644 --- a/app/api/server/route.ts +++ b/app/api/server/route.ts @@ -1,4 +1,3 @@ -import { ServerApi } from "@/app/[locale]/types/nezha-api"; import { auth } from "@/auth"; import getEnv from "@/lib/env-entry"; import { GetNezhaData } from "@/lib/serverFetch"; @@ -7,37 +6,20 @@ import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; -interface NezhaDataResponse extends ServerApi { - error?: string; - cause?: string; - code?: string; -} - export const GET = auth(async function GET(req) { if (!req.auth && getEnv("SitePassword")) { redirect("/"); } - const response = (await GetNezhaData()) as NezhaDataResponse; - if (response.error) { - return NextResponse.json({ error: response.error }, { status: 400 }); + try { + const data = await GetNezhaData(); + return NextResponse.json(data, { status: 200 }); + } catch (error) { + console.error("Error in GET handler:", error); + // @ts-ignore + const statusCode = error.statusCode || 500; + // @ts-ignore + const message = error.message || "Internal Server Error"; + return NextResponse.json({ error: message }, { status: statusCode }); } - if (response.cause) { - console.log("GetNezhaData error(cause):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - if (response.code === "ConnectionRefused") { - console.log("GetNezhaData error(code):", response); - return NextResponse.json( - { cause: "server connect error" }, - { status: 400 }, - ); - } - if (!response.result) { - return NextResponse.json({ cause: "fetch data empty" }, { status: 400 }); - } - return NextResponse.json(response, { status: 200 }); }); diff --git a/lib/serverFetch.tsx b/lib/serverFetch.tsx index ebb2c0b..4cbf3bb 100644 --- a/lib/serverFetch.tsx +++ b/lib/serverFetch.tsx @@ -8,18 +8,17 @@ import { unstable_noStore as noStore } from "next/cache"; export async function GetNezhaData() { noStore(); - var nezhaBaseUrl = getEnv("NezhaBaseUrl"); + let nezhaBaseUrl = getEnv("NezhaBaseUrl"); if (!nezhaBaseUrl) { - console.log("NezhaBaseUrl is not set"); - return { error: "NezhaBaseUrl is not set" }; + console.error("NezhaBaseUrl is not set"); + throw new Error("NezhaBaseUrl is not set"); } // Remove trailing slash - if (nezhaBaseUrl[nezhaBaseUrl.length - 1] === "/") { - nezhaBaseUrl = nezhaBaseUrl.slice(0, -1); - } + nezhaBaseUrl = nezhaBaseUrl.replace(/\/$/, ""); + try { - const response = await fetch(nezhaBaseUrl + "/api/v1/server/details", { + const response = await fetch(`${nezhaBaseUrl}/api/v1/server/details`, { headers: { Authorization: getEnv("NezhaAuth") as string, }, @@ -27,12 +26,19 @@ export async function GetNezhaData() { revalidate: 0, }, }); - const resData = await response.json(); - const nezhaData = resData.result as NezhaAPI[]; - if (!nezhaData) { - console.log(resData); - return { error: "NezhaData fetch failed" }; + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Failed to fetch data: ${response.status} ${errorText}`); } + + const resData = await response.json(); + + if (!resData.result) { + throw new Error("NezhaData fetch failed: 'result' field is missing"); + } + + const nezhaData = resData.result as NezhaAPI[]; const data: ServerApi = { live_servers: 0, offline_servers: 0, @@ -41,30 +47,27 @@ export async function GetNezhaData() { result: [], }; - var forceShowAllServers = getEnv("ForceShowAllServers"); - let nezhaDataFiltered: NezhaAPI[]; - if (forceShowAllServers === "true") { - nezhaDataFiltered = nezhaData; - } else { - // remove hidden servers - nezhaDataFiltered = nezhaData.filter( - (element) => !element.hide_for_guest, - ); - } + const forceShowAllServers = getEnv("ForceShowAllServers") === "true"; + const nezhaDataFiltered = forceShowAllServers + ? nezhaData + : nezhaData.filter((element) => !element.hide_for_guest); const timestamp = Date.now() / 1000; data.result = nezhaDataFiltered.map( (element: MakeOptional) => { - if (timestamp - element.last_active > 300) { - data.offline_servers += 1; - element.online_status = false; - } else { + const isOnline = timestamp - element.last_active <= 300; + element.online_status = isOnline; + + if (isOnline) { data.live_servers += 1; - element.online_status = true; + } else { + data.offline_servers += 1; } + data.total_out_bandwidth += element.status.NetOutTransfer; data.total_in_bandwidth += element.status.NetInTransfer; + // Remove unwanted properties delete element.ipv4; delete element.ipv6; delete element.valid_ip; @@ -75,26 +78,24 @@ export async function GetNezhaData() { return data; } catch (error) { - console.log("GetServerDetail error:", error); - return error; + console.error("GetNezhaData error:", error); + throw error; // Rethrow the error to be caught by the caller } } export async function GetServerMonitor({ server_id }: { server_id: number }) { - var nezhaBaseUrl = getEnv("NezhaBaseUrl"); + let nezhaBaseUrl = getEnv("NezhaBaseUrl"); if (!nezhaBaseUrl) { - console.log("NezhaBaseUrl is not set"); - return { error: "NezhaBaseUrl is not set" }; + console.error("NezhaBaseUrl is not set"); + throw new Error("NezhaBaseUrl is not set"); } // Remove trailing slash - if (nezhaBaseUrl[nezhaBaseUrl.length - 1] === "/") { - nezhaBaseUrl = nezhaBaseUrl.slice(0, -1); - } + nezhaBaseUrl = nezhaBaseUrl.replace(/\/$/, ""); try { const response = await fetch( - nezhaBaseUrl + `/api/v1/monitor/${server_id}`, + `${nezhaBaseUrl}/api/v1/monitor/${server_id}`, { headers: { Authorization: getEnv("NezhaAuth") as string, @@ -104,34 +105,40 @@ export async function GetServerMonitor({ server_id }: { server_id: number }) { }, }, ); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Failed to fetch data: ${response.status} ${errorText}`); + } + const resData = await response.json(); const monitorData = resData.result; + if (!monitorData) { - console.log(resData); - return { error: "MonitorData fetch failed" }; + console.error("MonitorData fetch failed:", resData); + throw new Error("MonitorData fetch failed: 'result' field is missing"); } + return monitorData; } catch (error) { - console.error(error); - return error; + console.error("GetServerMonitor error:", error); + throw error; } } export async function GetServerDetail({ server_id }: { server_id: number }) { - var nezhaBaseUrl = getEnv("NezhaBaseUrl"); + let nezhaBaseUrl = getEnv("NezhaBaseUrl"); if (!nezhaBaseUrl) { - console.log("NezhaBaseUrl is not set"); - return { error: "NezhaBaseUrl is not set" }; + console.error("NezhaBaseUrl is not set"); + throw new Error("NezhaBaseUrl is not set"); } // Remove trailing slash - if (nezhaBaseUrl[nezhaBaseUrl.length - 1] === "/") { - nezhaBaseUrl = nezhaBaseUrl.slice(0, -1); - } + nezhaBaseUrl = nezhaBaseUrl.replace(/\/$/, ""); try { const response = await fetch( - nezhaBaseUrl + `/api/v1/server/details?id=${server_id}`, + `${nezhaBaseUrl}/api/v1/server/details?id=${server_id}`, { headers: { Authorization: getEnv("NezhaAuth") as string, @@ -141,31 +148,38 @@ export async function GetServerDetail({ server_id }: { server_id: number }) { }, }, ); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Failed to fetch data: ${response.status} ${errorText}`); + } + const resData = await response.json(); const detailDataList = resData.result; - if (!detailDataList) { - console.log(resData); - return { error: "MonitorData fetch failed" }; + + if ( + !detailDataList || + !Array.isArray(detailDataList) || + detailDataList.length === 0 + ) { + console.error("MonitorData fetch failed:", resData); + throw new Error( + "MonitorData fetch failed: 'result' field is missing or empty", + ); } const timestamp = Date.now() / 1000; - const detailData = detailDataList.map( - (element: MakeOptional) => { - if (timestamp - element.last_active > 300) { - element.online_status = false; - } else { - element.online_status = true; - } - delete element.ipv4; - delete element.ipv6; - delete element.valid_ip; - return element; - }, - )[0]; + const detailData = detailDataList.map((element) => { + element.online_status = timestamp - element.last_active <= 300; + delete element.ipv4; + delete element.ipv6; + delete element.valid_ip; + return element; + })[0]; return detailData; } catch (error) { - console.error(error); - return error; + console.error("GetServerDetail error:", error); + throw error; // Rethrow the error to be handled by the caller } }