diff --git a/src/application/ReferenceSourceVcsAdapter.ts b/src/application/ReferenceSourceVcsAdapter.ts index c47cd60f3c..cd372e230d 100644 --- a/src/application/ReferenceSourceVcsAdapter.ts +++ b/src/application/ReferenceSourceVcsAdapter.ts @@ -9,6 +9,7 @@ import { RegularFileCleanupFailure, retryRegularFileCleanup, } from "./RegularFileRead.js"; +import { referenceSourceResourceFailure } from "../reference/ReferenceSourceReaderErrors.js"; import type { ReferenceSourceReaderError } from "../reference/ReferenceSourceReaderTypes.js"; export type ReferenceSourceVcsInfo = @@ -59,13 +60,7 @@ export const readReferenceSourceVcs = async ( }); } catch (cause: unknown) { if (!(cause instanceof ArtifactReaderFailure)) throw cause; - return err({ - tag: "reference-source-reader", - code: cause.reason === "cancelled" ? "cancelled" : "io", - message: cause.message, - ...(cause.cleanup === undefined ? {} : { cleanup: cause.cleanup }), - cause, - }); + return err(referenceSourceResourceFailure(cause)); } }; diff --git a/src/reference/ReferenceSourceReader.ts b/src/reference/ReferenceSourceReader.ts index 4af7da9de2..0b43b55f96 100644 --- a/src/reference/ReferenceSourceReader.ts +++ b/src/reference/ReferenceSourceReader.ts @@ -19,6 +19,7 @@ import { noFollowOpenSupported, prepareRoot, } from "./ReferenceSourceReaderValidate.js"; +import { referenceSourceResourceFailure } from "./ReferenceSourceReaderErrors.js"; const PATH_RACE_LIMITATION = "Path identity is revalidated around operations; Node lacks portable descriptor-relative openat traversal, so a syscall-boundary pathname race remains."; @@ -33,13 +34,7 @@ export const readReferenceSource = async ( return await resources.run(() => readSource(root, resources, options)); } catch (cause: unknown) { if (!(cause instanceof ArtifactReaderFailure)) throw cause; - return err({ - tag: "reference-source-reader", - code: cause.reason === "cancelled" ? "cancelled" : "io", - message: cause.message, - ...(cause.cleanup === undefined ? {} : { cleanup: cause.cleanup }), - cause, - }); + return err(referenceSourceResourceFailure(cause)); } }; diff --git a/src/reference/ReferenceSourceReaderErrors.ts b/src/reference/ReferenceSourceReaderErrors.ts index 2c826b4c96..85e02be759 100644 --- a/src/reference/ReferenceSourceReaderErrors.ts +++ b/src/reference/ReferenceSourceReaderErrors.ts @@ -1,3 +1,4 @@ +import type { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js"; import type { ReferenceSourceEntry, ReferenceSourceFailureCode, @@ -16,6 +17,17 @@ export const failure = ( export const cancelled = (): ReferenceSourceReaderError => failure("cancelled", "Reference source traversal cancelled"); +/** Project resource failures into the reference-source error contract. */ +export const referenceSourceResourceFailure = ( + cause: ArtifactReaderFailure, +): ReferenceSourceReaderError => ({ + tag: "reference-source-reader", + code: cause.reason === "cancelled" ? "cancelled" : "io", + message: cause.message, + ...(cause.cleanup === undefined ? {} : { cleanup: cause.cleanup }), + cause, +}); + export const safeSize = (size: bigint): number | undefined => { const value = Number(size); return Number.isSafeInteger(value) && value >= 0 ? value : undefined;