mirror of
https://github.com/morluto/rea.git
synced 2026-11-06 06:46:10 +00:00
Keep failed stable-read handles and WABT runtime roots under retryable resource scopes. Preserve cancellation causes and primary errors, close the same service instances bound to MCP tools, and consolidate CLI operation/cleanup projection. Validation: fast typecheck and lint, cached runtime build, docs checks, SDK schema validation, focused service and real-file cleanup tests, CLI cleanup regressions, and MCP lifecycle/shutdown workflows. Provider process fixtures simulate engine output; real WABT and Linux EVM execution are not established by this pass.
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
|
|
import {
|
|
AnalysisError,
|
|
type AnalysisPartialObservation,
|
|
} from "../domain/analysisErrorBase.js";
|
|
import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
|
|
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
import type { Result } from "../domain/result.js";
|
|
|
|
/** Finish a one-shot CLI operation without discarding its primary result on close failure. */
|
|
export const finishAnalysisCommand = async <
|
|
Value extends AnalysisPartialObservation,
|
|
>(
|
|
run: () => Promise<Result<Value, AnalysisError>>,
|
|
service: { close(): Promise<void> },
|
|
providerId: string,
|
|
canonicalOperation: string,
|
|
fallbackResource?: string,
|
|
): Promise<Value | ReturnType<typeof projectAnalysisError>> => {
|
|
let result: Result<Value, AnalysisError>;
|
|
try {
|
|
result = await run();
|
|
} catch (cause) {
|
|
result = {
|
|
ok: false,
|
|
error:
|
|
cause instanceof AnalysisError
|
|
? cause
|
|
: new ProviderAdapterError(providerId, canonicalOperation, { cause }),
|
|
};
|
|
}
|
|
try {
|
|
await service.close();
|
|
} catch (cause) {
|
|
let cleanup: AnalysisError;
|
|
if (cause instanceof AnalysisError) cleanup = cause;
|
|
else {
|
|
const observation =
|
|
cause instanceof ArtifactReaderFailure
|
|
? ArtifactReaderFailure.cleanupObservation(
|
|
cause,
|
|
fallbackResource ?? `${canonicalOperation} resources`,
|
|
)
|
|
: {
|
|
reason: cause instanceof Error ? cause.message : String(cause),
|
|
resources: [],
|
|
};
|
|
cleanup = new ProviderCleanupError(
|
|
providerId,
|
|
observation.resources,
|
|
{ reason: observation.reason },
|
|
{ cause, operation: canonicalOperation },
|
|
);
|
|
}
|
|
if (result.ok) cleanup.retainPartialObservation(result.value);
|
|
return projectAnalysisError(
|
|
result.ok
|
|
? cleanup
|
|
: analysisErrorWithCleanupFailure(
|
|
result.error,
|
|
cleanup,
|
|
canonicalOperation,
|
|
),
|
|
);
|
|
}
|
|
return result.ok ? result.value : projectAnalysisError(result.error);
|
|
};
|