|
| 1 | +import { expect, test } from "bun:test"; |
| 2 | + |
| 3 | +import { stripErrorStack } from "./index"; |
| 4 | + |
| 5 | +/** |
| 6 | + * The deployed public overlay API was returning `data.stack` — internal file |
| 7 | + * paths and line numbers — to anyone who sent a bad overlay token. tRPC adds it |
| 8 | + * unless it believes it's in production, and a Worker's NODE_ENV isn't a reliable |
| 9 | + * signal, so it is stripped unconditionally. |
| 10 | + */ |
| 11 | + |
| 12 | +test("stripErrorStack removes the stack from an error shape", () => { |
| 13 | + const shape = { |
| 14 | + message: "Invalid overlay token.", |
| 15 | + code: -32001, |
| 16 | + data: { |
| 17 | + code: "UNAUTHORIZED", |
| 18 | + httpStatus: 401, |
| 19 | + path: "state.getPublic", |
| 20 | + stack: "TRPCError: Invalid overlay token.\n at assertToken (index.js:28330:11)", |
| 21 | + }, |
| 22 | + }; |
| 23 | + const out = stripErrorStack(shape); |
| 24 | + expect("stack" in out.data).toBe(false); |
| 25 | + expect(JSON.stringify(out)).not.toContain("index.js"); |
| 26 | + // Everything a client legitimately needs survives. |
| 27 | + expect(out.message).toBe("Invalid overlay token."); |
| 28 | + expect(out.code).toBe(-32001); |
| 29 | + expect(out.data.code).toBe("UNAUTHORIZED"); |
| 30 | + expect(out.data.httpStatus).toBe(401); |
| 31 | + expect(out.data.path).toBe("state.getPublic"); |
| 32 | +}); |
| 33 | + |
| 34 | +test("stripErrorStack leaves a shape that never had a stack alone", () => { |
| 35 | + const shape = { message: "nope", code: -32600, data: { code: "BAD_REQUEST", httpStatus: 400 } }; |
| 36 | + expect(stripErrorStack(shape)).toEqual(shape); |
| 37 | +}); |
| 38 | + |
| 39 | +test("stripErrorStack preserves the zodError payload the client renders", () => { |
| 40 | + const shape = { |
| 41 | + message: "Input validation failed", |
| 42 | + code: -32600, |
| 43 | + data: { |
| 44 | + code: "BAD_REQUEST", |
| 45 | + httpStatus: 400, |
| 46 | + stack: "at zod", |
| 47 | + zodError: { fieldErrors: { goals: ["Required"] } }, |
| 48 | + }, |
| 49 | + }; |
| 50 | + const out = stripErrorStack(shape); |
| 51 | + expect("stack" in out.data).toBe(false); |
| 52 | + expect(out.data.zodError).toEqual({ fieldErrors: { goals: ["Required"] } }); |
| 53 | +}); |
0 commit comments