From d2937fd26aa8870b3e4a7af01f1c8c25a0722492 Mon Sep 17 00:00:00 2001 From: Manus Date: Wed, 30 Sep 2026 14:03:41 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20journaliser=20le=20code=20SQL=20sans=20p?= =?UTF-8?q?aram=C3=A8tre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/webImportSourcesError.test.ts | 14 +++++++++++++- server/webImportSourcesError.ts | 20 ++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/server/webImportSourcesError.test.ts b/server/webImportSourcesError.test.ts index 347f5a6..b104677 100644 --- a/server/webImportSourcesError.test.ts +++ b/server/webImportSourcesError.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "vitest"; -import { WEB_IMPORT_SOURCE_SAVE_ERROR, getSafeWebImportSourceError } from "./webImportSourcesError"; +import { + WEB_IMPORT_SOURCE_SAVE_ERROR, + getSafeWebImportSourceError, + getWebImportSourceTechnicalCode, +} from "./webImportSourcesError"; describe("getSafeWebImportSourceError", () => { it("never returns the SQL statement or connector parameters to the client", () => { @@ -14,4 +18,12 @@ describe("getSafeWebImportSourceError", () => { expect(safeError.message).not.toContain("insert into"); expect(safeError.message).not.toContain("secret-value"); }); + + it("retient uniquement le code du pilote, même lorsque celui-ci est imbriqué", () => { + const databaseError = Object.assign(new Error("params: user@example.fr, secret-value"), { + cause: { code: "ER_NO_SUCH_TABLE", message: "contains secret-value" }, + }); + + expect(getWebImportSourceTechnicalCode(databaseError)).toBe("ER_NO_SUCH_TABLE"); + }); }); diff --git a/server/webImportSourcesError.ts b/server/webImportSourcesError.ts index 907846a..edebe04 100644 --- a/server/webImportSourcesError.ts +++ b/server/webImportSourcesError.ts @@ -14,12 +14,24 @@ export function getSafeWebImportSourceError(_error: unknown): TRPCError { }); } +/** Extrait uniquement le code du pilote, sans conserver son message ni ses paramètres. */ +export function getWebImportSourceTechnicalCode(error: unknown): string { + if (!error || typeof error !== "object") return "unknown"; + + const directCode = "code" in error && typeof error.code === "string" ? error.code : null; + if (directCode) return directCode; + + const cause = "cause" in error ? error.cause : null; + if (cause && typeof cause === "object" && "code" in cause && typeof cause.code === "string") { + return cause.code; + } + + return "unknown"; +} + /** Journalise uniquement les métadonnées techniques non sensibles. */ export function logWebImportSourceSaveFailure(error: unknown): void { - const technicalCode = - error && typeof error === "object" && "code" in error && typeof error.code === "string" - ? error.code - : "unknown"; + const technicalCode = getWebImportSourceTechnicalCode(error); console.error("[WebImportSources] Échec d’enregistrement", { technicalCode }); }