fix(agent-api): wrap all six agent routes in a catch-all error handler
Every /api/owner/* and /api/client/* route wraps its body in try/catch; none of the six /api/agent/* routes did, so an unexpected failure (e.g. a PocketBase validation error partway through the subtasks loop) surfaced as Next's default non-JSON 500 instead of the jsonError shape this surface otherwise guarantees everywhere else. A caller retrying after an opaque 500 mid-loop could also create duplicate subtasks for ones that already succeeded. Follows the exact pattern already used by src/app/api/owner/cards/[id]/move/route.ts: requireAgentToken and the initial body-parse/validation stay outside the try (they touch no PocketBase and already return correctly-shaped errors); everything after is wrapped, with a route-specific console.error prefix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e486bd818c
commit
76a012bb43
5 changed files with 223 additions and 196 deletions
|
|
@ -37,6 +37,7 @@ export async function PATCH(
|
|||
return jsonError("A destination column name is required", 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const pb = await getAdminPb();
|
||||
const card = await pb.collection("cards").getOne<CardRecord>(cardId).catch(() => null);
|
||||
if (!card || card.archived) return jsonError("Card not found", 404);
|
||||
|
|
@ -100,4 +101,8 @@ export async function PATCH(
|
|||
column: destination.name,
|
||||
accepted: updated.accepted,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[agent-api] move card failed", error);
|
||||
return jsonError("Something went wrong", 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ export async function GET(
|
|||
if (denied) return denied;
|
||||
|
||||
const { cardId } = await context.params;
|
||||
|
||||
try {
|
||||
const pb = await getAdminPb();
|
||||
|
||||
const card = await pb.collection("cards").getOne<CardRecord>(cardId).catch(() => null);
|
||||
|
|
@ -85,4 +87,8 @@ export async function GET(
|
|||
authored_at: commit.authored_at,
|
||||
})),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[agent-api] get card failed", error);
|
||||
return jsonError("Something went wrong", 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export async function POST(
|
|||
return jsonError("At least one non-empty title is required", 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const pb = await getAdminPb();
|
||||
const card = await pb.collection("cards").getOne<CardRecord>(cardId).catch(() => null);
|
||||
if (!card || card.archived) return jsonError("Card not found", 404);
|
||||
|
|
@ -65,4 +66,8 @@ export async function POST(
|
|||
}
|
||||
|
||||
return jsonOk({ created }, 201);
|
||||
} catch (error) {
|
||||
console.error("[agent-api] create subtask failed", error);
|
||||
return jsonError("Something went wrong", 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ export async function GET(
|
|||
if (denied) return denied;
|
||||
|
||||
const { projectId } = await context.params;
|
||||
|
||||
try {
|
||||
const pb = await getAdminPb();
|
||||
|
||||
const project = await pb.collection("projects").getOne(projectId).catch(() => null);
|
||||
|
|
@ -69,4 +71,8 @@ export async function GET(
|
|||
.filter((c): c is NonNullable<typeof c> => c !== null);
|
||||
|
||||
return jsonOk(out);
|
||||
} catch (error) {
|
||||
console.error("[agent-api] list project cards failed", error);
|
||||
return jsonError("Something went wrong", 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { getAdminPb } from "@/lib/pb/admin";
|
||||
import { requireAgentToken } from "@/lib/agent/auth";
|
||||
import { jsonOk } from "@/lib/http/json";
|
||||
import { jsonError, jsonOk } from "@/lib/http/json";
|
||||
import type { ClientRecord, ProjectRecord } from "@/lib/pb/types";
|
||||
|
||||
/**
|
||||
|
|
@ -14,6 +14,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||
const denied = requireAgentToken(request);
|
||||
if (denied) return denied;
|
||||
|
||||
try {
|
||||
const pb = await getAdminPb();
|
||||
|
||||
const [projects, clients] = await Promise.all([
|
||||
|
|
@ -39,4 +40,8 @@ export async function GET(request: Request): Promise<Response> {
|
|||
.filter((p): p is NonNullable<typeof p> => p !== null);
|
||||
|
||||
return jsonOk(out);
|
||||
} catch (error) {
|
||||
console.error("[agent-api] list projects failed", error);
|
||||
return jsonError("Something went wrong", 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue