抠图输入超限返回明确的请求错误状态
This commit is contained in:
parent
6e4350fe2b
commit
751cffae05
@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
|
|||||||
import { ZodError } from "zod";
|
import { ZodError } from "zod";
|
||||||
|
|
||||||
import { auth } from "@/app/(auth)/auth";
|
import { auth } from "@/app/(auth)/auth";
|
||||||
|
import { RmbgServiceError } from "@/lib/ai/rmbg/service";
|
||||||
import { canvasCapabilityClientCommandSchema } from "@/lib/canvas/capabilities/client-command";
|
import { canvasCapabilityClientCommandSchema } from "@/lib/canvas/capabilities/client-command";
|
||||||
import { CanvasCapabilityRuntimeError } from "@/lib/canvas/capabilities/context";
|
import { CanvasCapabilityRuntimeError } from "@/lib/canvas/capabilities/context";
|
||||||
import { getCanvasCapabilityManifest } from "@/lib/canvas/capabilities/registry";
|
import { getCanvasCapabilityManifest } from "@/lib/canvas/capabilities/registry";
|
||||||
@ -90,7 +91,7 @@ export async function POST(
|
|||||||
const failure = getRequestFailureDetails(error, "执行画布能力失败");
|
const failure = getRequestFailureDetails(error, "执行画布能力失败");
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, error: formatRequestFailure(failure, requestId), failure, requestId },
|
{ success: false, error: formatRequestFailure(failure, requestId), failure, requestId },
|
||||||
{ status: 500 }
|
{ status: error instanceof RmbgServiceError ? error.status : 500 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,31 @@ test("AOS input rejections retain their cause instead of becoming a generic proc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("the canvas API returns input-limit errors as HTTP 400 and preserves the same advice when polling", async () => {
|
||||||
|
const service = rmbgLoader(async () => { throw new Error("Unexpected provider call"); });
|
||||||
|
const error = new service.RmbgServiceError("抠图参考图分辨率超限(5056×3392 像素),当前 AOS 上游要求宽、高均不超过 4096 像素。", 400);
|
||||||
|
const route = serverLoader({
|
||||||
|
"@/app/(auth)/auth": { auth: async () => ({ user: { id: "user-a" } }) },
|
||||||
|
"@/lib/ai/rmbg/service": { RmbgServiceError: service.RmbgServiceError },
|
||||||
|
"@/lib/canvas/capabilities/client-command": { canvasCapabilityClientCommandSchema: { parse: (v: unknown) => v } },
|
||||||
|
"@/lib/canvas/capabilities/context": { CanvasCapabilityRuntimeError: class extends Error {} },
|
||||||
|
"@/lib/canvas/agent-mutations": { CanvasAgentMutationError: class extends Error {} },
|
||||||
|
"@/lib/canvas/capabilities/registry": { getCanvasCapabilityManifest: () => [] },
|
||||||
|
"@/lib/canvas/capabilities/runtime": { executeCanvasCapabilityRuntime: async () => { throw error; } },
|
||||||
|
"@/lib/canvas/capabilities/task-store": { getCanvasCapabilityTask: async () => ({ id: "task-a", status: "failed", error: error.message }) },
|
||||||
|
})("app/api/canvas/[id]/capabilities/route.ts");
|
||||||
|
const params = { params: Promise.resolve({ id: "project-a" }) };
|
||||||
|
const response = await route.POST(new Request("https://example.com/api/canvas/project-a/capabilities", { method: "POST", body: JSON.stringify({ requestId: "request-a" }) }), params);
|
||||||
|
expect(response.status).toBe(400);
|
||||||
|
const submitted = await response.json();
|
||||||
|
expect(submitted.failure).toMatchObject({ code: "RMBG_INPUT_RESOLUTION_EXCEEDED", outcome: "failed" });
|
||||||
|
expect(submitted.error).toContain("5056×3392");
|
||||||
|
expect(submitted.error).toContain("本次未提交上游抠图任务");
|
||||||
|
const polled = await (await route.GET(new Request("https://example.com/api/canvas/project-a/capabilities?requestId=request-a"), params)).json();
|
||||||
|
expect(polled.task.failure).toEqual(submitted.failure);
|
||||||
|
expect(polled.task.error).toContain(submitted.failure.recommendation);
|
||||||
|
});
|
||||||
|
|
||||||
test("a create timeout preserves its cause and never creates another paid task", async () => {
|
test("a create timeout preserves its cause and never creates another paid task", async () => {
|
||||||
const image = await sharp({ create: { width: 16, height: 16, channels: 3, background: "white" } }).png().toBuffer();
|
const image = await sharp({ create: { width: 16, height: 16, channels: 3, background: "white" } }).png().toBuffer();
|
||||||
let creates = 0;
|
let creates = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user