Merge pull request #1256 from morluto/fix/evidence-file-selection-code

fix(errors): report caller-selected evidence path failures as invalid input
This commit is contained in:
Kaoru0822 2026-10-09 02:46:04 -07:00 committed by GitHub
commit d4a598e936
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 5 deletions

View File

@ -119,6 +119,13 @@ export const analysisErrorCategory = (
return "unavailable";
if (error instanceof ArtifactOperationError)
return artifactErrorCategory(error.reason);
if (
error instanceof EvidenceFileError &&
(error.reason === "missing" ||
error.reason === "not-file" ||
error.reason === "exists")
)
return "invalid_input";
return STATIC_ERROR_CATEGORIES[error._tag] ?? "execution_failure";
};

View File

@ -11,7 +11,7 @@ import {
import { ArtifactOperationError } from "./artifactOperationError.js";
import { BinaryTargetError } from "./configurationErrors.js";
import { BrowserObservationError } from "./browserObservationError.js";
import { EvidenceIntegrityError } from "./evidenceErrors.js";
import { EvidenceFileError, EvidenceIntegrityError } from "./evidenceErrors.js";
import {
HopperProcessError,
HopperRemoteError,
@ -573,3 +573,32 @@ describe("analysis error projection: operational diagnostics", () => {
expect(unknown.remediation.action).toContain("provider_operation_health");
});
});
describe("analysis error projection: evidence files", () => {
it.each([
["read", "missing", "invalid_request", "invalid_input"],
["read", "not-file", "invalid_request", "invalid_input"],
["write", "missing", "invalid_request", "invalid_input"],
["write", "exists", "invalid_request", "invalid_input"],
[
"read",
"invalid-json",
"evidence_integrity_mismatch",
"execution_failure",
],
["read", "io", "execution_failure", "execution_failure"],
] as const)(
"classifies a %s %s evidence file by who can correct it",
(operation, reason, code, category) => {
const projected = projectAnalysisError(
new EvidenceFileError(operation, reason, { path: "/selected.json" }),
);
expect(projected).toMatchObject({
code,
category,
details: { operation, reason, path: "/selected.json" },
});
expect(analysisErrorProjectionSchema.parse(projected)).toEqual(projected);
},
);
});

View File

@ -144,10 +144,12 @@ const artifactOperationCode = (
const evidenceFileCode = (
reason: EvidenceFileError["reason"],
): AnalysisErrorProjection["code"] =>
reason === "invalid-json"
? "evidence_integrity_mismatch"
: "execution_failure";
): AnalysisErrorProjection["code"] => {
if (reason === "invalid-json") return "evidence_integrity_mismatch";
// A missing, non-file or already-existing path is the caller's selection.
if (reason === "io") return "execution_failure";
return "invalid_request";
};
const unknownRegistryCode = (
reason: UnknownRegistryError["reason"],