From 44bbd13b5579da809a6a6beabf9932f73a73b0cf Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Wed, 11 Nov 2026 07:00:47 -0500 Subject: [PATCH] fix: preserve capture configuration failures --- src/application/WebScriptExportService.ts | 11 ++++++++++ .../filesystem/webScriptExport.test.ts | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/application/WebScriptExportService.ts b/src/application/WebScriptExportService.ts index 24bcaab43e..e8d8b37e60 100644 --- a/src/application/WebScriptExportService.ts +++ b/src/application/WebScriptExportService.ts @@ -17,6 +17,7 @@ import { AnalysisOutputError, } from "../domain/analysisErrorCore.js"; import { AnalysisError } from "../domain/analysisErrorBase.js"; +import { ConfigurationError } from "../domain/configurationErrors.js"; import { createEvidence, type Evidence } from "../domain/evidence.js"; import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js"; import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js"; @@ -323,6 +324,16 @@ const captureReadFailure = ( "Capture read and file-handle close both failed", { cause }, ); + if (cause instanceof ConfigurationError) { + if (closeFailure === undefined) return cause; + return new ConfigurationError(cause.message, { + cause: causeWithClose, + settings: cause.settings, + ...(cause.remediationAction === undefined + ? {} + : { remediationAction: cause.remediationAction }), + }); + } const code = cause instanceof Error && "code" in cause ? String(cause.code) : ""; if (code === "EACCES" || code === "EPERM") diff --git a/tests/boundary/filesystem/webScriptExport.test.ts b/tests/boundary/filesystem/webScriptExport.test.ts index a4bb2e544b..59564300a7 100644 --- a/tests/boundary/filesystem/webScriptExport.test.ts +++ b/tests/boundary/filesystem/webScriptExport.test.ts @@ -1498,3 +1498,25 @@ it.each(["basename", "directory"])( ).toEqual(result.scripts); }, ); + +it("retains invalid Windows ChangeTime configuration at the capture read boundary", async () => { + const { input, resources } = await setup(); + const platform = Object.getOwnPropertyDescriptor(process, "platform")!; + const previous = process.env.REA_WINDOWS_CHANGE_TIME_DRIFT_MS; + try { + Object.defineProperty(process, "platform", { value: "win32" }); + process.env.REA_WINDOWS_CHANGE_TIME_DRIFT_MS = "invalid"; + const result = await exportWebScripts(input, resources); + expect(result.ok).toBe(false); + if (result.ok) throw new Error("Expected configuration refusal"); + expect(projectAnalysisError(result.error)).toMatchObject({ + code: "configuration_invalid", + details: { settings: [{ setting: "REA_WINDOWS_CHANGE_TIME_DRIFT_MS" }] }, + }); + } finally { + Object.defineProperty(process, "platform", platform); + if (previous === undefined) + delete process.env.REA_WINDOWS_CHANGE_TIME_DRIFT_MS; + else process.env.REA_WINDOWS_CHANGE_TIME_DRIFT_MS = previous; + } +});