fix(filesystem): preserve opaque caller reasons through cleanup

Do not interpret exact caller cancellation reasons as descriptor ownership records. Preserve checkpoint-shaped reasons through successful close retry and supply cancellation context in direct signal-aware cleanup consumers.

Validation: 156 focused tests across 14 files passed; no native provider execution. Refs #4610
This commit is contained in:
morluto committed 2026-10-17 08:25:01 +08:00
1 parent 3bd9aa3484
commit 746a044e42
5 files changed
+91 -34

No files matched your search

+7 -2
View File
@@ -43,13 +43,15 @@ export type RegularFileReadOutcome<Value> = RegularFileOperationOutcome<Value>;
export const retryRegularFileCleanup = async <Value>(
failure: RegularFileCleanupFailure<Value>,
resources: ArtifactResourceScope,
signal?: AbortSignal,
): Promise<{
readonly outcome: RegularFileReadOutcome<Value>;
readonly cleanup?: AnalysisCleanupObservation;
}> => {
const outcome: RegularFileReadOutcome<Value> =
failure.outcome.kind === "failed" &&
failure.outcome.cause instanceof RegularFileOperationCancelled
failure.outcome.cause instanceof RegularFileOperationCancelled &&
!(signal?.aborted === true && failure.outcome.cause === signal.reason)
? { kind: "failed", cause: failure.outcome.cause.reason }
: failure.outcome;
const released = await resources.release({
@@ -106,6 +108,9 @@ export const withRegularFile = async <Value>(
},
);
} catch (cause: unknown) {
// Caller reasons are opaque, including objects shaped like file failures.
// They do not transfer ownership of any descriptor to this operation.
if (signal?.aborted === true && cause === signal.reason) throw cause;
if (cause instanceof RegularFileOperationCancelled) throw cause.reason;
if (
cause instanceof RegularFileCancelled &&
@@ -117,7 +122,7 @@ export const withRegularFile = async <Value>(
resources === undefined
)
throw cause;
const retry = await retryRegularFileCleanup(cause, resources);
const retry = await retryRegularFileCleanup(cause, resources, signal);
if (retry.cleanup !== undefined) throw cause;
if (retry.outcome.kind === "failed") throw retry.outcome.cause;
return retry.outcome.value;