fix(handler): 统一错误处理并替换Next.js重写为路由处理器
- 将所有handler中的Fail函数调用替换为FailError以统一错误处理 - 添加FailError函数实现统一的错误日志记录和响应格式 - 移除Next.js配置中的rewrites并实现统一的API路由代理处理器 - 新增路由处理器支持长连接和大文件上传场景的代理转发 - 更新错误处理逻辑避免将内部错误详情暴露给前端用户
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import type { NextConfig } from "next";
|
||||
import { PHASE_DEVELOPMENT_SERVER } from "next/constants";
|
||||
import { loadEnvConfig } from "@next/env";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
@@ -12,8 +11,6 @@ const localChangelog = readFileSync(resolve(webDir, "../CHANGELOG.md"), "utf8");
|
||||
|
||||
export default function nextConfig(phase: string): NextConfig {
|
||||
const isDev = phase === PHASE_DEVELOPMENT_SERVER;
|
||||
loadEnvConfig(resolve(webDir, ".."), isDev, undefined, true);
|
||||
const apiBaseUrl = process.env.API_BASE_URL || "http://127.0.0.1:8080";
|
||||
const releases = parseChangelog(localChangelog);
|
||||
|
||||
return {
|
||||
@@ -25,8 +22,5 @@ export default function nextConfig(phase: string): NextConfig {
|
||||
NEXT_PUBLIC_APP_VERSION: localVersion,
|
||||
NEXT_PUBLIC_APP_RELEASES: JSON.stringify(releases),
|
||||
},
|
||||
async rewrites() {
|
||||
return [{ source: "/api/:path*", destination: `${apiBaseUrl}/api/:path*` }];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const maxDuration = 300;
|
||||
|
||||
type RouteContext = {
|
||||
params: Promise<{ path: string[] }>;
|
||||
};
|
||||
|
||||
function proxyHeaders(request: NextRequest) {
|
||||
const headers = new Headers(request.headers);
|
||||
headers.delete("host");
|
||||
headers.delete("content-length");
|
||||
headers.delete("connection");
|
||||
return headers;
|
||||
}
|
||||
|
||||
function responseHeaders(response: Response) {
|
||||
const headers = new Headers(response.headers);
|
||||
headers.delete("content-length");
|
||||
headers.delete("content-encoding");
|
||||
headers.delete("transfer-encoding");
|
||||
return headers;
|
||||
}
|
||||
|
||||
async function proxy(request: NextRequest, context: RouteContext) {
|
||||
const { path } = await context.params;
|
||||
const apiBaseUrl = process.env.API_BASE_URL || "http://127.0.0.1:8080";
|
||||
const target = `${apiBaseUrl.replace(/\/$/, "")}/api/${path.map(encodeURIComponent).join("/")}${request.nextUrl.search}`;
|
||||
const hasBody = request.method !== "GET" && request.method !== "HEAD";
|
||||
|
||||
try {
|
||||
const response = await fetch(target, {
|
||||
method: request.method,
|
||||
headers: proxyHeaders(request),
|
||||
body: hasBody ? request.body : undefined,
|
||||
duplex: hasBody ? "half" : undefined,
|
||||
} as RequestInit & { duplex?: "half" });
|
||||
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: responseHeaders(response),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to proxy", target, error);
|
||||
return Response.json({ code: 1, data: null, msg: "接口连接失败,请确认后端服务已启动" }, { status: 502 });
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxy;
|
||||
export const HEAD = proxy;
|
||||
export const POST = proxy;
|
||||
export const PUT = proxy;
|
||||
export const PATCH = proxy;
|
||||
export const DELETE = proxy;
|
||||
export const OPTIONS = proxy;
|
||||
Reference in New Issue
Block a user