diff --git a/src/middleware/with-response-object-check.ts b/src/middleware/with-response-object-check.ts index 9f8cae0..01ee2cb 100644 --- a/src/middleware/with-response-object-check.ts +++ b/src/middleware/with-response-object-check.ts @@ -1,4 +1,3 @@ -import { ResponseValidationError } from "./http-exceptions.js" import { Middleware } from "./types.js" import { RouteSpec } from "src/types/route-spec.js" @@ -10,7 +9,7 @@ export const withResponseObjectCheck: Middleware< if (typeof rawResponse === "object" && !(rawResponse instanceof Response)) { throw new Error( - "Use ctx.json({...}) instead of returning an object directly." + "Route handlers must return a Response. Use ctx.json(...) instead of returning an object directly." ) } diff --git a/tests/errors/do-not-allow-raw-json.test.ts b/tests/errors/do-not-allow-raw-json.test.ts index 8682796..a6b8301 100644 --- a/tests/errors/do-not-allow-raw-json.test.ts +++ b/tests/errors/do-not-allow-raw-json.test.ts @@ -33,7 +33,35 @@ test("should throw an error when responding with raw JSON", async (t) => { }) t.true( data.error.includes( - "Use ctx.json({...}) instead of returning an object directly" + "Use ctx.json(...) instead of returning an object directly" ) ) }) + +test("should log a clear ctx.json instruction for raw object responses", async (t) => { + const { axios, getLogs } = await getTestRoute(t, { + globalSpec: { + authMiddleware: {}, + }, + routeSpec: { + methods: ["GET"], + jsonBody: z.any(), + jsonResponse: z.any(), + }, + routePath: "/", + routeFn: () => { + return { foo: "bar" } as any + }, + }) + + const response = await axios.get("/", { validateStatus: () => true }) + t.is(response.status, 500) + + const logs = getLogs() + const errorLogText = logs.error + .flat() + .map((entry) => (entry instanceof Error ? entry.message : String(entry))) + .join("\n") + + t.true(errorLogText.includes("Use ctx.json(...) instead of returning an object directly")) +})