feat(admin): add structured error logger for all API routes
Replace bare console.error() calls with logError() utility across all 47 API route handlers. logError() prints timestamp + context + message + stack trace + extra request data to stderr, and redacts sensitive fields (password, token, secret, key, etc.) from logged objects.
This commit is contained in:
parent
12c249596a
commit
3773fdc780
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { createModel, updateModel, deleteModel } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -11,7 +12,7 @@ export async function POST(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Create model error:", msg);
|
||||
logError("Create model error:", e);
|
||||
return NextResponse.json({ error: `创建失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -27,7 +28,7 @@ export async function PATCH(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Update model error:", msg);
|
||||
logError("Update model error:", e);
|
||||
return NextResponse.json({ error: `更新失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -42,7 +43,7 @@ export async function DELETE(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Delete model error:", msg);
|
||||
logError("Delete model error:", e);
|
||||
return NextResponse.json({ error: `删除失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { updatePricing } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -15,7 +16,7 @@ export async function PATCH(
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Update pricing error:", msg);
|
||||
logError("Update pricing error:", e);
|
||||
return NextResponse.json({ error: `更新失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { createProvider, updateProvider, deleteProvider } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -11,7 +12,7 @@ export async function POST(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Create provider error:", msg);
|
||||
logError("Create provider error:", e);
|
||||
return NextResponse.json({ error: `创建失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -27,7 +28,7 @@ export async function PATCH(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Update provider error:", msg);
|
||||
logError("Update provider error:", e);
|
||||
return NextResponse.json({ error: `更新失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -42,7 +43,7 @@ export async function DELETE(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Delete provider error:", msg);
|
||||
logError("Delete provider error:", e);
|
||||
return NextResponse.json({ error: `删除失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { createVersion, updateVersion, deleteVersion } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -11,7 +12,7 @@ export async function POST(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Create version error:", msg);
|
||||
logError("Create version error:", e);
|
||||
return NextResponse.json({ error: `创建失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -27,7 +28,7 @@ export async function PATCH(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Update version error:", msg);
|
||||
logError("Update version error:", e);
|
||||
return NextResponse.json({ error: `更新失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -42,7 +43,7 @@ export async function DELETE(req: NextRequest) {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Delete version error:", msg);
|
||||
logError("Delete version error:", e);
|
||||
return NextResponse.json({ error: `删除失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -45,7 +46,7 @@ export async function GET() {
|
||||
|
||||
return NextResponse.json({ config });
|
||||
} catch (e) {
|
||||
console.error("Get AI config error:", e);
|
||||
logError("Get AI config error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -95,7 +96,7 @@ export async function PUT(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Update AI config error:", e);
|
||||
logError("Update AI config error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -149,7 +150,7 @@ export async function POST(req: NextRequest) {
|
||||
aiSummaryUsed: !!aiSummary,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("[daily-report] Error:", e);
|
||||
logError("[daily-report] Error:", e);
|
||||
return NextResponse.json({ error: String(e) }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -484,7 +485,7 @@ async function sendEmail(opts: {
|
||||
sentCount++;
|
||||
console.log(`[daily-report] Sent to ${recipient}`);
|
||||
} catch (e) {
|
||||
console.error(`[daily-report] Failed to send to ${recipient}:`, e);
|
||||
logError(`[daily-report] Failed to send to ${recipient}:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -66,7 +67,7 @@ export async function PATCH(
|
||||
if (err?.code === "23505") {
|
||||
return NextResponse.json({ error: "该邮箱已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("Update recipient error:", e);
|
||||
logError("Update recipient error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -99,7 +100,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete recipient error:", e);
|
||||
logError("Delete recipient error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -14,7 +15,7 @@ export async function GET() {
|
||||
);
|
||||
return NextResponse.json({ recipients: result.rows });
|
||||
} catch (e) {
|
||||
console.error("[recipients] List error:", e);
|
||||
logError("[recipients] List error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -53,7 +54,7 @@ export async function POST(req: NextRequest) {
|
||||
if (err?.code === "23505") {
|
||||
return NextResponse.json({ error: "该邮箱已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("[recipients] Add error:", e);
|
||||
logError("[recipients] Add error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -38,7 +39,7 @@ export async function GET() {
|
||||
);
|
||||
return NextResponse.json({ recipients: result.rows });
|
||||
} catch (e) {
|
||||
console.error("List recipients error:", e);
|
||||
logError("List recipients error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -78,7 +79,7 @@ export async function POST(req: NextRequest) {
|
||||
if (err?.code === "23505") {
|
||||
return NextResponse.json({ error: "该邮箱已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("Add recipient error:", e);
|
||||
logError("Add recipient error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query, transaction } from "@/lib/db";
|
||||
|
||||
@ -41,7 +42,7 @@ export async function GET(
|
||||
})),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Project billing error:", e);
|
||||
logError("Project billing error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -82,7 +83,7 @@ export async function POST(
|
||||
|
||||
return NextResponse.json({ ok: true, amount });
|
||||
} catch (e) {
|
||||
console.error("Project add credit error:", e);
|
||||
logError("Project add credit error:", e);
|
||||
return NextResponse.json({ error: "充值失败" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -48,7 +49,7 @@ export async function PATCH(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Update project member error:", e);
|
||||
logError("Update project member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -90,7 +91,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete project member error:", e);
|
||||
logError("Delete project member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -38,7 +39,7 @@ export async function GET(
|
||||
|
||||
return NextResponse.json({ members });
|
||||
} catch (e) {
|
||||
console.error("List project members error:", e);
|
||||
logError("List project members error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -108,7 +109,7 @@ export async function POST(
|
||||
|
||||
return NextResponse.json({ success: true, id: result.rows[0]?.id }, { status: 201 });
|
||||
} catch (e) {
|
||||
console.error("Add project member error:", e);
|
||||
logError("Add project member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -56,7 +57,7 @@ export async function GET(
|
||||
billingHistory: billingHistoryRows.rows,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Project detail error:", e);
|
||||
logError("Project detail error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -64,7 +65,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ projects: projects.rows, total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("List projects error:", e);
|
||||
logError("List projects error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -108,7 +109,7 @@ export async function GET(
|
||||
|
||||
return NextResponse.json({ repo, branches, commits });
|
||||
} catch (e) {
|
||||
console.error("Repo detail error:", e);
|
||||
logError("Repo detail error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { deleteApiToken } from "@/lib/api-token";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -29,7 +30,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete token error:", e);
|
||||
logError("Delete token error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
listApiTokens,
|
||||
@ -11,7 +12,7 @@ export async function GET(req: NextRequest) {
|
||||
const tokens = await listApiTokens();
|
||||
return NextResponse.json({ tokens });
|
||||
} catch (e) {
|
||||
console.error("List tokens error:", e);
|
||||
logError("List tokens error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -58,7 +59,7 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ id: result.id, token, name: name.trim(), expiresAt }, { status: 201 });
|
||||
} catch (e) {
|
||||
console.error("Create token error:", e);
|
||||
logError("Create token error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { login, buildSetCookieHeader } from "@/lib/auth";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -70,7 +71,7 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.error("Login error:", e);
|
||||
logError("Login error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { logout, parseSessionCookie, loadAdminSession, buildClearCookieHeader } from "@/lib/auth";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -31,7 +32,7 @@ export async function POST(req: NextRequest) {
|
||||
response.headers.set("Set-Cookie", buildClearCookieHeader());
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.error("Logout error:", e);
|
||||
logError("Logout error:", e);
|
||||
const response = NextResponse.json({ success: false });
|
||||
response.headers.set("Set-Cookie", buildClearCookieHeader());
|
||||
return response;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { parseSessionCookie, loadAdminSession, touchSession } from "@/lib/auth";
|
||||
|
||||
@ -29,7 +30,7 @@ export async function GET(req: NextRequest) {
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Session check error:", e);
|
||||
logError("Session check error:", e);
|
||||
return NextResponse.json({ user: null });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -132,7 +133,7 @@ export async function GET() {
|
||||
await ensureTables();
|
||||
return NextResponse.json({ status: "ok" }, { status: 200 });
|
||||
} catch (e) {
|
||||
console.error("[Health] DB check failed:", e);
|
||||
logError("[Health] DB check failed:", e);
|
||||
return NextResponse.json({ status: "error", reason: String(e) }, { status: 503 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { listAuditLogs } from "@/lib/log";
|
||||
|
||||
@ -87,7 +88,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json(result);
|
||||
} catch (e) {
|
||||
console.error("List audit logs error:", e);
|
||||
logError("List audit logs error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
listPermissions,
|
||||
@ -19,7 +20,7 @@ export async function GET() {
|
||||
const permissions = await listPermissions();
|
||||
return NextResponse.json({ permissions });
|
||||
} catch (e) {
|
||||
console.error("List permissions error:", e);
|
||||
logError("List permissions error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -63,7 +64,7 @@ export async function POST(req: NextRequest) {
|
||||
if ((e as { code?: string }).code === "23505") {
|
||||
return NextResponse.json({ error: "权限代码已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("Create permission error:", e);
|
||||
logError("Create permission error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -97,7 +98,7 @@ export async function PUT(req: NextRequest) {
|
||||
|
||||
return NextResponse.json(permission);
|
||||
} catch (e) {
|
||||
console.error("Update permission error:", e);
|
||||
logError("Update permission error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -125,7 +126,7 @@ export async function DELETE(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete permission error:", e);
|
||||
logError("Delete permission error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -76,7 +77,7 @@ export async function GET() {
|
||||
last24h: parseInt(last24h.rows[0]?.count || "0", 10),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Activity stats error:", e);
|
||||
logError("Activity stats error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -97,7 +98,7 @@ export async function GET(req: NextRequest) {
|
||||
versions: versionsList,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("AI data error:", e);
|
||||
logError("AI data error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextResponse } from "next/server";
|
||||
import { syncModels } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -12,7 +13,7 @@ export async function POST() {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("AI sync error:", msg);
|
||||
logError("AI sync error:", e);
|
||||
return NextResponse.json({ error: `同步失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextResponse } from "next/server";
|
||||
import { checkAlerts } from "@/lib/adminrpc/client";
|
||||
|
||||
@ -12,7 +13,7 @@ export async function POST() {
|
||||
return NextResponse.json(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error("Alert check error:", msg);
|
||||
logError("Alert check error:", e);
|
||||
return NextResponse.json({ error: `检查失败: ${msg}` }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -99,7 +100,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ logs: combined.slice(0, pageSize), total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("Platform audit logs error:", e);
|
||||
logError("Platform audit logs error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -90,7 +91,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ repos, total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("Repos error:", e);
|
||||
logError("Repos error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { getAdminUserId } from "@/lib/auth";
|
||||
@ -30,7 +31,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Revoke message error:", e);
|
||||
logError("Revoke message error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -72,7 +73,7 @@ export async function GET(
|
||||
|
||||
return NextResponse.json({ messages, total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("Room messages error:", e);
|
||||
logError("Room messages error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -90,7 +91,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ rooms, total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("Rooms error:", e);
|
||||
logError("Rooms error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
getOnlinePlatformSessions,
|
||||
@ -22,7 +23,7 @@ export async function GET() {
|
||||
}
|
||||
return NextResponse.json({ sessions });
|
||||
} catch (e) {
|
||||
console.error("Get platform sessions error:", e);
|
||||
logError("Get platform sessions error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -51,7 +52,7 @@ export async function DELETE(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: ok });
|
||||
} catch (e) {
|
||||
console.error("Delete platform session error:", e);
|
||||
logError("Delete platform session error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -73,7 +74,7 @@ export async function GET() {
|
||||
planDistribution,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Stats error:", e);
|
||||
logError("Stats error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -45,7 +46,7 @@ export async function GET(
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Get user error:", e);
|
||||
logError("Get user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -145,7 +146,7 @@ export async function PATCH(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Update user error:", e);
|
||||
logError("Update user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -55,7 +56,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ users, total, page, pageSize });
|
||||
} catch (e) {
|
||||
console.error("Platform users error:", e);
|
||||
logError("Platform users error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -110,7 +111,7 @@ export async function PATCH(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: true, updated: uids.length });
|
||||
} catch (e) {
|
||||
console.error("Batch update user status error:", e);
|
||||
logError("Batch update user status error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query, getClient } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -94,7 +95,7 @@ export async function POST(
|
||||
|
||||
return NextResponse.json({ success: true, amount, currency });
|
||||
} catch (e) {
|
||||
console.error("Add workspace credit error:", e);
|
||||
logError("Add workspace credit error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query, getClient } from "@/lib/db";
|
||||
import { getAdminUserId } from "@/lib/auth";
|
||||
@ -35,7 +36,7 @@ export async function GET(
|
||||
);
|
||||
return NextResponse.json({ configs: result.rows });
|
||||
} catch (e) {
|
||||
console.error("Alert config error:", e);
|
||||
logError("Alert config error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -87,7 +88,7 @@ export async function PUT(
|
||||
client.release();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Alert config update error:", e);
|
||||
logError("Alert config update error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -52,7 +53,7 @@ export async function PATCH(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Update workspace member error:", e);
|
||||
logError("Update workspace member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -94,7 +95,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete workspace member error:", e);
|
||||
logError("Delete workspace member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -43,7 +44,7 @@ export async function GET(
|
||||
|
||||
return NextResponse.json({ members });
|
||||
} catch (e) {
|
||||
console.error("List workspace members error:", e);
|
||||
logError("List workspace members error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -113,7 +114,7 @@ export async function POST(
|
||||
|
||||
return NextResponse.json({ success: true, id: result.rows[0]?.id }, { status: 201 });
|
||||
} catch (e) {
|
||||
console.error("Add workspace member error:", e);
|
||||
logError("Add workspace member error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
|
||||
@ -59,7 +60,7 @@ export async function GET(
|
||||
billingHistory: billing.rows,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Workspace detail error:", e);
|
||||
logError("Workspace detail error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { query } from "@/lib/db";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -61,7 +62,7 @@ export async function GET(req: NextRequest) {
|
||||
pageSize,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("List workspaces error:", e);
|
||||
logError("List workspaces error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -108,7 +109,7 @@ export async function PATCH(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: true, updated: ids.length });
|
||||
} catch (e) {
|
||||
console.error("Batch update workspace plan error:", e);
|
||||
logError("Batch update workspace plan error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
getRoleById,
|
||||
@ -27,7 +28,7 @@ export async function GET(
|
||||
const permissions = await getRolePermissions(roleId);
|
||||
return NextResponse.json({ ...role, permissions });
|
||||
} catch (e) {
|
||||
console.error("Get role error:", e);
|
||||
logError("Get role error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -66,7 +67,7 @@ export async function PUT(
|
||||
|
||||
return NextResponse.json(role);
|
||||
} catch (e) {
|
||||
console.error("Update role error:", e);
|
||||
logError("Update role error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -94,7 +95,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete role error:", e);
|
||||
logError("Delete role error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
listRoles,
|
||||
@ -19,7 +20,7 @@ export async function GET() {
|
||||
const roles = await listRoles();
|
||||
return NextResponse.json({ roles });
|
||||
} catch (e) {
|
||||
console.error("List roles error:", e);
|
||||
logError("List roles error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -60,7 +61,7 @@ export async function POST(req: NextRequest) {
|
||||
if ((e as { code?: string }).code === "23505") {
|
||||
return NextResponse.json({ error: "角色名已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("Create role error:", e);
|
||||
logError("Create role error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getOnlineSessions } from "@/lib/redis";
|
||||
import { createAuditLog } from "@/lib/log";
|
||||
@ -14,7 +15,7 @@ export async function GET() {
|
||||
const sessions = await getOnlineSessions();
|
||||
return NextResponse.json({ sessions });
|
||||
} catch (e) {
|
||||
console.error("Get sessions error:", e);
|
||||
logError("Get sessions error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -44,7 +45,7 @@ export async function DELETE(req: NextRequest) {
|
||||
|
||||
return NextResponse.json({ success: ok });
|
||||
} catch (e) {
|
||||
console.error("Delete session error:", e);
|
||||
logError("Delete session error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
getUserById,
|
||||
@ -32,7 +33,7 @@ export async function GET(
|
||||
|
||||
return NextResponse.json({ ...safeUser, roles });
|
||||
} catch (e) {
|
||||
console.error("Get user error:", e);
|
||||
logError("Get user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -80,7 +81,7 @@ export async function PUT(
|
||||
const { password_hash: _, ...safeUser } = user;
|
||||
return NextResponse.json(safeUser);
|
||||
} catch (e) {
|
||||
console.error("Update user error:", e);
|
||||
logError("Update user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -113,7 +114,7 @@ export async function DELETE(
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error("Delete user error:", e);
|
||||
logError("Delete user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { logError } from "@/lib/logger";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
listUsers,
|
||||
@ -24,7 +25,7 @@ export async function GET(req: NextRequest) {
|
||||
const result = await listUsers({ page, pageSize, search });
|
||||
return NextResponse.json(result);
|
||||
} catch (e) {
|
||||
console.error("List users error:", e);
|
||||
logError("List users error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -70,7 +71,7 @@ export async function POST(req: NextRequest) {
|
||||
if ((e as { code?: string }).code === "23505") {
|
||||
return NextResponse.json({ error: "用户名已存在" }, { status: 409 });
|
||||
}
|
||||
console.error("Create user error:", e);
|
||||
logError("Create user error:", e);
|
||||
return NextResponse.json({ error: "服务器错误" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
70
admin/src/lib/logger.ts
Normal file
70
admin/src/lib/logger.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Structured error logger for the admin module.
|
||||
*
|
||||
* All API route errors should use this instead of bare console.error.
|
||||
* Prints: [timestamp] [ERROR] context | message | stack | extra
|
||||
*/
|
||||
|
||||
export interface LogExtra {
|
||||
method?: string;
|
||||
url?: string;
|
||||
params?: Record<string, unknown>;
|
||||
body?: unknown;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and print a detailed error to stderr.
|
||||
* @param context Short label describing where the error occurred (e.g. "GET /api/users")
|
||||
* @param error The caught error (any type)
|
||||
* @param extra Optional additional context (request method, url, params, etc.)
|
||||
*/
|
||||
export function logError(context: string, error: unknown, extra?: LogExtra): void {
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// Extract best-effort message
|
||||
let message = "unknown error";
|
||||
if (error instanceof Error) {
|
||||
message = error.message;
|
||||
} else if (typeof error === "string") {
|
||||
message = error;
|
||||
} else if (error && typeof error === "object" && "message" in error) {
|
||||
message = String((error as { message: unknown }).message);
|
||||
}
|
||||
|
||||
// Extract stack trace
|
||||
let stack = "";
|
||||
if (error instanceof Error && error.stack) {
|
||||
stack = error.stack;
|
||||
}
|
||||
|
||||
const extraStr = extra
|
||||
? ` | extra: ${JSON.stringify(redact(extra))}`
|
||||
: "";
|
||||
|
||||
// Multi-line format for easy grepping
|
||||
console.error(
|
||||
`[${timestamp}] [ERROR] ${context}` +
|
||||
`\n message: ${message}` +
|
||||
(stack ? `\n stack: ${stack}` : "") +
|
||||
extraStr
|
||||
);
|
||||
}
|
||||
|
||||
/** Recursively remove sensitive fields before logging */
|
||||
function redact(obj: unknown, depth = 0): unknown {
|
||||
if (depth > 4) return "[max-depth]";
|
||||
if (obj === null || obj === undefined) return obj;
|
||||
if (typeof obj !== "object") return obj;
|
||||
if (Array.isArray(obj)) return obj.map((v) => redact(v, depth + 1));
|
||||
const sensitive = ["password", "token", "secret", "key", "authorization", "cookie", "api_key"];
|
||||
const result: Record<string, unknown> = {};
|
||||
for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {
|
||||
if (sensitive.some((s) => k.toLowerCase().includes(s))) {
|
||||
result[k] = "[REDACTED]";
|
||||
} else {
|
||||
result[k] = redact(v, depth + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user