mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
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:
1 parent
3bd9aa3484
commit
746a044e42
5 files changed
+91
-34
No files matched your search
@@ -108,8 +108,9 @@ const buildIgnored = async (
|
||||
try {
|
||||
text = await readRegularFileText(policyPath, { signal });
|
||||
} catch (cause: unknown) {
|
||||
if (signal?.aborted === true && cause === signal.reason) throw cause;
|
||||
if (!(cause instanceof RegularFileCleanupFailure)) throw cause;
|
||||
const retry = await retryRegularFileCleanup(cause, resources);
|
||||
const retry = await retryRegularFileCleanup(cause, resources, signal);
|
||||
if (retry.cleanup !== undefined) {
|
||||
const primary =
|
||||
retry.outcome.kind === "failed"
|
||||
|
||||
@@ -88,8 +88,9 @@ const resolveSourceHead = async (
|
||||
try {
|
||||
return await readRegularFile(path, { signal });
|
||||
} catch (cause: unknown) {
|
||||
if (signal?.aborted === true && cause === signal.reason) throw cause;
|
||||
if (!(cause instanceof RegularFileCleanupFailure)) throw cause;
|
||||
const retry = await retryRegularFileCleanup(cause, resources);
|
||||
const retry = await retryRegularFileCleanup(cause, resources, signal);
|
||||
if (
|
||||
retry.outcome.kind === "failed" &&
|
||||
errorCode(retry.outcome.cause) !== "ENOENT"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -236,8 +236,10 @@ const readCapture = async (
|
||||
try {
|
||||
return ok({ bytes: await readRegularFile(path, { signal }) });
|
||||
} catch (cause: unknown) {
|
||||
if (signal?.aborted === true && cause === signal.reason)
|
||||
return err(captureReadFailure(path, cause, signal));
|
||||
if (cause instanceof RegularFileCleanupFailure) {
|
||||
const retry = await retryRegularFileCleanup(cause, resources);
|
||||
const retry = await retryRegularFileCleanup(cause, resources, signal);
|
||||
const cleanup = {
|
||||
reason: retry.cleanup?.reason ?? errorMessage(cause.cleanupCause),
|
||||
incomplete: retry.cleanup !== undefined,
|
||||
|
||||
Reference in new issue
Block a user