From 34fd7bdf7d7aeec83d0380254ca9e0f7149c98ef Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:19:28 +0800 Subject: [PATCH] refactor(reference): share resource failure projection --- src/application/ReferenceSourceVcsAdapter.ts | 9 ++------- src/reference/ReferenceSourceReader.ts | 9 ++------- src/reference/ReferenceSourceReaderErrors.ts | 12 ++++++++++++ 3 files changed, 16 insertions(+), 14 deletions(-) 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;