From 3643e94e167479fc0bba154552d04884ce5302ab Mon Sep 17 00:00:00 2001 From: Vishal Katyal Date: Thu, 13 Aug 2026 14:44:29 -0400 Subject: [PATCH] fix(rest/nodejs): answer simulate-shipping order-not-found with the UCP error envelope --- rest/nodejs/src/api/testing.ts | 9 ++++++++- rest/nodejs/test/error_envelope.test.ts | 27 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/rest/nodejs/src/api/testing.ts b/rest/nodejs/src/api/testing.ts index 872308b..187960d 100644 --- a/rest/nodejs/src/api/testing.ts +++ b/rest/nodejs/src/api/testing.ts @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { ResourceNotFoundError, ucpErrorResponse } from "../utils/ucp_error"; import { type IdParamContext } from "../utils/validation"; import { CheckoutService } from "./checkout"; @@ -33,7 +34,13 @@ export class TestingService { return c.json({ status: "shipped" }, 200); } catch (e: any) { if (e.message === "Order not found") { - return c.json({ detail: "Order not found" }, 404); + // The Python reference answers this with the UCP error envelope + // (services/checkout_service.py ship_order raises + // ResourceNotFoundError -> server.py ucp_exception_handler). + return ucpErrorResponse( + c, + new ResourceNotFoundError("Order not found") + ); } return c.json({ detail: e.message }, 500); } diff --git a/rest/nodejs/test/error_envelope.test.ts b/rest/nodejs/test/error_envelope.test.ts index b9256a6..75de216 100644 --- a/rest/nodejs/test/error_envelope.test.ts +++ b/rest/nodejs/test/error_envelope.test.ts @@ -19,6 +19,7 @@ import { zValidator } from "@hono/zod-validator"; import { Hono } from "hono"; import { CheckoutService } from "../src/api/checkout"; +import { TestingService } from "../src/api/testing"; import { getProductsDb, getTransactionsDb, initDbs } from "../src/data/db"; import { CheckoutCompleteRequestSchema, @@ -67,6 +68,12 @@ function buildApp() { zValidator("param", IdParamSchema, prettyValidation), svc.cancelCheckout ); + const testingSvc = new TestingService(svc); + app.post( + "/testing/simulate-shipping/:id", + zValidator("param", IdParamSchema, prettyValidation), + testingSvc.shipOrder + ); return app; } @@ -167,6 +174,26 @@ test("unknown checkout id answers 404 with a RESOURCE_NOT_FOUND envelope", async assertUcpError((await res.json()) as UcpErrorBody, "RESOURCE_NOT_FOUND"); }); +// The Python reference envelopes this same failure through +// ResourceNotFoundError (services/checkout_service.py ship_order -> +// server.py ucp_exception_handler); the Node twin answered a flat +// { detail } until this test's fix. +test("simulate-shipping an unknown order answers 404 with a RESOURCE_NOT_FOUND envelope", async () => { + const app = buildApp(); + const res = await app.request( + "/testing/simulate-shipping/ord_missing_envelope", + { + method: "POST", + headers: { + "Simulation-Secret": + process.env.SIMULATION_SECRET || "super-secret-sim-key", + }, + } + ); + assert.equal(res.status, 404); + assertUcpError((await res.json()) as UcpErrorBody, "RESOURCE_NOT_FOUND"); +}); + test("updating a canceled checkout answers 409 with a CHECKOUT_NOT_MODIFIABLE envelope", async () => { const app = buildApp(); const created = (await (await create(app)).json()) as { id: string };