mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
fix(reference): preserve import cancellation provenance (#9597)
* fix(reference): preserve import cancellation reason * test(reference): cover null cancellation during failed cleanup * test(reference): always release fixture directory
This commit is contained in:
1 parent
e66e92904e
commit
e8d1bbc98b
9 files changed
+149
-31
No files matched your search
@@ -69,7 +69,8 @@ export const traverseDirectory = async (
|
||||
current.path,
|
||||
state.signal,
|
||||
);
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
if (!before.ok) {
|
||||
recordDirectoryFailure(
|
||||
state,
|
||||
@@ -103,11 +104,12 @@ export const traverseDirectory = async (
|
||||
// A directory that cannot be opened retains its ordinary partial-entry
|
||||
// failure; only an opened directory needs policy before enumeration.
|
||||
result = isAborted(state.signal)
|
||||
? err(cancelled())
|
||||
? err(cancelled(state.signal))
|
||||
: ((await state.beforeDirectory?.(
|
||||
pathFromRoot(state.root, current.path),
|
||||
)) ?? ok(undefined));
|
||||
if (result.ok && isAborted(state.signal)) result = err(cancelled());
|
||||
if (result.ok && isAborted(state.signal))
|
||||
result = err(cancelled(state.signal));
|
||||
while (result.ok) {
|
||||
let child: Dirent | null;
|
||||
try {
|
||||
@@ -154,7 +156,7 @@ export const traverseDirectory = async (
|
||||
const previous = result.ok ? undefined : result.error.cleanup;
|
||||
const primary = result.ok
|
||||
? isAborted(state.signal)
|
||||
? cancelled()
|
||||
? cancelled(state.signal)
|
||||
: failure(
|
||||
"io",
|
||||
readFailure?.localDiagnostic ??
|
||||
@@ -173,12 +175,13 @@ export const traverseDirectory = async (
|
||||
...new Set([...previous.resources, ...observation.resources]),
|
||||
],
|
||||
},
|
||||
cause: primary.cause ?? cleanup.cause,
|
||||
cause: Object.hasOwn(primary, "cause") ? primary.cause : cleanup.cause,
|
||||
});
|
||||
}
|
||||
if (!result.ok) return result;
|
||||
}
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
if (readFailure !== undefined) {
|
||||
recordDirectoryFailure(
|
||||
state,
|
||||
@@ -196,7 +199,8 @@ export const traverseDirectory = async (
|
||||
current.path,
|
||||
state.signal,
|
||||
);
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
if (!after.ok || !sameFile(before.stats, after.stats)) {
|
||||
recordDirectoryFailure(
|
||||
state,
|
||||
@@ -263,11 +267,13 @@ const processEntry = async (
|
||||
name: string,
|
||||
directories: PendingDirectory[],
|
||||
): Promise<ReferenceSourceResult<undefined>> => {
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
const absolute = join(current.path, name);
|
||||
const path = pathFromRoot(state.root, absolute);
|
||||
const metadata = await readMetadata(absolute);
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
if (!metadata.ok) {
|
||||
const excluded = applyExclusion(state.shouldExclude, path, "unknown");
|
||||
if (!excluded.ok)
|
||||
@@ -312,7 +318,8 @@ const processEntry = async (
|
||||
state.exclusions.push({ path, kind });
|
||||
return { ok: true, value: undefined };
|
||||
}
|
||||
if (isAborted(state.signal)) return { ok: false, error: cancelled() };
|
||||
if (isAborted(state.signal))
|
||||
return { ok: false, error: cancelled(state.signal) };
|
||||
if (kind === "symlink")
|
||||
state.entries.push(
|
||||
await readStableSymlinkTarget(
|
||||
@@ -370,6 +377,11 @@ const processFileEntry = async (
|
||||
? entry.message
|
||||
: `Reference file cleanup failed: ${path}`,
|
||||
cleanup: result.cleanup,
|
||||
...(entry.status === "failed" &&
|
||||
entry.code === "cancelled" &&
|
||||
state.signal?.aborted === true
|
||||
? { cause: state.signal.reason }
|
||||
: {}),
|
||||
});
|
||||
return ok(undefined);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user