* fix(pcap): report workspace allocation failures by their system cause Pcap workspace allocation and snapshot writes mapped every filesystem error, including ENOTDIR and EACCES from mkdtemp, to a file-size resource constraint with null limits and worker file-size advice. Flutter's owned snapshot storage had the same errno-blind mapping, while TShark and sigrok carried duplicate copies of the correct split. Move the private-workspace failure projection into one shared owner: ENOSPC/EDQUOT/EFBIG stay file-size resource constraints with their system code and path; descriptor exhaustion and every other failure become provider workspace failures carrying stage, workspace path, failing path, system code and cause-specific recovery. Fixes #6123 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(flutter): locate owned storage failures by their workspace mapOwnedIoFailure always passed a null workspace path, so a descriptor write or read failure without its own errno path lost every location. Thread the owned root through: allocation keeps null (no workspace yet), snapshot failures use the allocated root, and package-reader system errors propagate to the request owner, which maps them against the snapshot root instead of mapping early without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import { expect, it } from "vitest";
|
|
|
|
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
import { privateWorkspaceFailure } from "./privateWorkspaceFailure.js";
|
|
|
|
const failure = (code: string | undefined, path?: string) =>
|
|
Object.assign(new Error(`${code ?? "plain"} failure`), {
|
|
...(code === undefined ? {} : { code }),
|
|
...(path === undefined ? {} : { path }),
|
|
});
|
|
|
|
it("keeps EFBIG as a file-size refusal with the worker file-size recovery", () => {
|
|
const projection = projectAnalysisError(
|
|
privateWorkspaceFailure("p", "op", failure("EFBIG", "/w/f"), "/w"),
|
|
);
|
|
expect(projection).toMatchObject({
|
|
code: "resource_constraint",
|
|
details: {
|
|
resource: "file-size",
|
|
reported_limits: {
|
|
workspace_path: "/w",
|
|
path: "/w/f",
|
|
system_code: "EFBIG",
|
|
},
|
|
},
|
|
remediation: {
|
|
action: expect.stringContaining("worker file-size") as unknown,
|
|
},
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
["errno without a path", failure("EIO"), "EIO", "/w"],
|
|
["error without errno", failure(undefined), null, "/w"],
|
|
["non-Error value", "unexpected", null, "/w"],
|
|
])(
|
|
"falls back to the workspace coordinate for %s",
|
|
(_name, cause, code, path) => {
|
|
const projection = projectAnalysisError(
|
|
privateWorkspaceFailure("p", "op", cause, "/w"),
|
|
);
|
|
expect(projection).toMatchObject({
|
|
code: "execution_failure",
|
|
details: {
|
|
provider_id: "p",
|
|
diagnostics: {
|
|
stage: "workspace",
|
|
workspace_path: "/w",
|
|
path,
|
|
system_code: code,
|
|
},
|
|
},
|
|
});
|
|
expect(projection.message).not.toContain("()");
|
|
},
|
|
);
|