From 98b15503e8ba503b51cab286a06ff6681a33dc55 Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 19 May 2026 13:08:25 -0500 Subject: [PATCH] Expose trusted cloud import errors --- server/src/__tests__/error-handler.test.ts | 25 ++++++++++++++++++++++ server/src/middleware/error-handler.ts | 11 +++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/src/__tests__/error-handler.test.ts b/server/src/__tests__/error-handler.test.ts index d01a8c3cf86..483403e047c 100644 --- a/server/src/__tests__/error-handler.test.ts +++ b/server/src/__tests__/error-handler.test.ts @@ -37,6 +37,31 @@ describe("errorHandler", () => { expect(res.__errorContext?.error?.message).toBe("boom"); }); + it("exposes raw 500 messages for trusted Cloud tenant imports", () => { + const req = { + ...makeReq(), + method: "POST", + originalUrl: "/api/companies/import", + actor: { + type: "board", + userId: "cloud-user", + source: "cloud_tenant", + }, + } as unknown as Request; + const res = makeRes() as any; + const next = vi.fn() as unknown as NextFunction; + const err = new Error("portable file references missing upload id"); + + errorHandler(err, req, res, next); + + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ + error: "Internal server error", + message: "portable file references missing upload id", + }); + expect(res.err).toBe(err); + }); + it("attaches HttpError instances for 500 responses", () => { const req = makeReq(); const res = makeRes() as any; diff --git a/server/src/middleware/error-handler.ts b/server/src/middleware/error-handler.ts index 032b5e1f19e..a25c8b0c43e 100644 --- a/server/src/middleware/error-handler.ts +++ b/server/src/middleware/error-handler.ts @@ -74,5 +74,14 @@ export function errorHandler( const tc = getTelemetryClient(); if (tc) trackErrorHandlerCrash(tc, { errorCode: rootError.name }); - res.status(500).json({ error: "Internal server error" }); + res.status(500).json({ + error: "Internal server error", + ...(shouldExposeTrustedCloudTenantImportError(req) ? { message: rootError.message } : {}), + }); +} + +function shouldExposeTrustedCloudTenantImportError(req: Request) { + return req.actor?.source === "cloud_tenant" + && req.method === "POST" + && req.originalUrl.split("?")[0] === "/api/companies/import"; }