Files
webstudio/apps/builder/app/services/api-errors.server.test.ts
Oleg Isonen dd99d27e5e fix: Stop returning unqueryable unpublish jobs (#6588)
Unpublish finishes in the request, but it returned a job ID that
`get-publish-job` could never find. It now returns the domains it
unpublished. A missing publish job also stays a normal not-found error
instead of suggesting a CLI update.

Closes #6578

## Changes
- Keep filename-based E2E shard discovery. Rebalance the files across
ten shards using measured CI times; each shard keeps its own test
environment and the same 12-minute safety timeout.
- Remove the fabricated unpublish job ID. `get-publish-job` remains for
publish jobs.
- Remove publish-only flags from the unpublish CLI and clarify CLI/MCP
guidance.
- Keep legacy optional server inputs for compatibility. The API input
contract does not change; clients that read the old `jobId` result need
to use `unpublishedDomains` instead.
- No database migration. Existing domain-removal behavior is unchanged,
including retention of other published domains.

## Checklist
- [x] Reproduced both reported failures with tests before the fix.
- [x] Reviewed the change for compatibility, redundant code, and
retained-domain behavior.
- [x] Updated the authoritative MCP docs and regenerated the CLI/MCP
docs.
- [x] Ran focused Builder, CLI, domain, and build tests; workspace
typecheck, lint, package-boundary, generated API, and generated-doc
checks.
- [x] Restore filename-based shard discovery and rebalance the files
across ten shards.
- [x] Verify every Chromium workflow test runs in exactly one shard and
update the E2E contributor docs. All 141 tests are assigned once across
the ten shards.
- [x] Verify parallel-safe long E2E files and the two-submission legacy
form test in CI.
- [x] Let independent slow E2E files run their tests concurrently; all
ten shard jobs passed.
- [ ] Confirm all E2E jobs finish in under five minutes. Eight did;
shard 1 took 5:10 and shard 4 took 6:32. Move the long Content-mode page
and shared-project bridge files to separate shards, then remeasure.
- [x] Required CI checks pass.

No live unpublish was run because it would change a published site.
Agent evaluations were not run; they require separate approval.
2026-10-23 18:59:44 +02:00

50 lines
1.5 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { TRPCError } from "@trpc/server";
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import {
procedure,
router,
type AppContext,
} from "@webstudio-is/trpc-interface/index.server";
import { throwApiError } from "./api-errors.server";
describe("api errors", () => {
test("throws public api trpc errors", () => {
expect.assertions(2);
try {
throwApiError("NOT_FOUND", "Missing");
} catch (error) {
expect(error).toBeInstanceOf(TRPCError);
expect(error).toMatchObject({
code: "NOT_FOUND",
message: "Missing",
cause: { webstudioCode: "NOT_FOUND" },
});
}
});
test("a missing record does not become a CLI version mismatch", async () => {
const response = await fetchRequestHandler({
endpoint: "/trpc",
req: new Request("http://localhost/trpc/missing"),
router: router({
missing: procedure.query(() => {
throwApiError("NOT_FOUND", "Publish job not found");
}),
}),
createContext: () =>
({
apiClient: { type: "cli" },
trpcCache: { setMaxAge: () => {} },
}) as unknown as AppContext,
});
expect(response.status).toBe(404);
const body = (await response.json()) as {
error: { data: Record<string, unknown> };
};
expect(body.error.data.webstudioCode).toBe("NOT_FOUND");
expect(body.error.data).not.toHaveProperty("apiCompatibility");
});
});