fix(mcp): classify project input validation (#455)
This commit is contained in:
parent
7f9d73102e
commit
b592dc5043
@ -75,7 +75,23 @@ describe("create_project MCP tool", () => {
|
||||
{ name: "Bad market", languageCode: "en" },
|
||||
toolContext,
|
||||
),
|
||||
).rejects.toThrow();
|
||||
).rejects.toMatchObject({ code: "VALIDATION_ERROR" });
|
||||
expect(mocks.createProject).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects an unsupported location as a readable validation error", async () => {
|
||||
const call = () =>
|
||||
createProjectTool.handler(
|
||||
{ name: "Bad location", locationCode: 999999 },
|
||||
toolContext,
|
||||
);
|
||||
|
||||
await expect(call()).rejects.toMatchObject({ code: "VALIDATION_ERROR" });
|
||||
// The message must name the offending field so the calling agent can
|
||||
// retry with a supported code, not just repeat the bare error code.
|
||||
await expect(call()).rejects.toThrow(
|
||||
"Unsupported DataForSEO location code",
|
||||
);
|
||||
expect(mocks.createProject).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { ProjectService } from "@/server/features/projects/services/ProjectService";
|
||||
import { AppError } from "@/server/lib/errors";
|
||||
import { mcpResponse } from "@/server/mcp/formatters";
|
||||
import { type ToolContext } from "@/server/mcp/context";
|
||||
import { optionalMetaOutputSchema } from "@/server/mcp/output-schemas";
|
||||
@ -65,9 +66,17 @@ export const createProjectTool = {
|
||||
handler: async (args: Args, context: ToolContext) => {
|
||||
const { baseUrl, ...auth } = context.auth;
|
||||
// Reuse the app's create schema so the market pair rule (a languageCode
|
||||
// requires a locationCode) is enforced identically to the dashboard, and
|
||||
// the domain is normalized the same way.
|
||||
const input = createProjectSchema.parse(args);
|
||||
// requires a locationCode) and domain normalization match the dashboard.
|
||||
// A rejection is bad caller input, not a fault: VALIDATION_ERROR keeps it
|
||||
// out of error reporting while still naming the bad field.
|
||||
const parsedInput = createProjectSchema.safeParse(args);
|
||||
if (!parsedInput.success) {
|
||||
throw new AppError(
|
||||
"VALIDATION_ERROR",
|
||||
z.prettifyError(parsedInput.error),
|
||||
);
|
||||
}
|
||||
const input = parsedInput.data;
|
||||
const project = await ProjectService.createProject(
|
||||
auth.organizationId,
|
||||
input,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user