Files
reverse-engineering-anything/src/domain/analysisErrorCore.ts
T
morluto d8c76b6296 fix(io): retain cleanup ownership and honor cancellation
Keep failed JSON read handles in the existing server resource scope and fail admission until cleanup succeeds. Thread cancellation through every process CLI input read and replace timer-driven cancellation checks with a shared first-read gate.

Classify authenticated standalone Evidence as wrong-kind input while preserving tampered-record integrity failures and actionable messages across ledger, CLI, and MCP consumers. Record unrelated CS_RESTRICT process neighbors as unverified without weakening related-process ownership checks. Update stale ADB fixtures for the actual shell protocol.

Validated focused CLI, MCP, filesystem, ownership, and error projection tests; static, docs, and duplication gates pass. The host-level CS_RESTRICT load reproduction was not run. Refs #2050, #2035, #2064.
2026-10-12 14:12:44 +08:00

165 lines
5.3 KiB
TypeScript

import type { JsonValue } from "./jsonValue.js";
import {
AnalysisError,
type AnalysisErrorOptions,
} from "./analysisErrorBase.js";
/** A readable supplied artifact lies outside this operation's supported target formats. */
export class AnalysisUnsupportedTargetError extends AnalysisError {
readonly _tag = "AnalysisUnsupportedTargetError";
/** Refusal-specific recovery, when the producer knows an available workflow. */
readonly remediationAction: string | undefined;
constructor(
readonly operation: string,
readonly path: string,
readonly reason: string,
options?: AnalysisErrorOptions & { readonly remediationAction?: string },
) {
super(`Unsupported target for ${operation} at ${path}: ${reason}`, options);
this.remediationAction = options?.remediationAction;
}
}
/** An analysis or transport resource failure, distinct from malformed input or unsupported coverage. */
export class AnalysisResourceConstraintError extends AnalysisError {
readonly _tag = "AnalysisResourceConstraintError";
readonly remediationAction: string | undefined;
constructor(
readonly operation: string,
readonly resource: "memory" | "cpu" | "file-size" | "transport",
readonly reason: string,
readonly reportedLimits: Readonly<Record<string, JsonValue>> | null,
options?: AnalysisErrorOptions & { readonly remediationAction?: string },
) {
super(`Resource constraint during ${operation}: ${reason}`, options);
this.remediationAction = options?.remediationAction;
}
}
/** Provider-neutral invalid analysis input or output at an application boundary. */
export class AnalysisProtocolError extends AnalysisError {
readonly _tag = "AnalysisProtocolError";
}
/** Caller input failed provider-neutral application parsing. */
export class AnalysisInputError extends AnalysisError {
readonly _tag = "AnalysisInputError";
override readonly userMessage: string | undefined;
constructor(
readonly operation: string,
options?: AnalysisErrorOptions & { readonly userMessage?: string },
readonly issues: readonly AnalysisInputIssue[] = [],
) {
super(`Invalid analysis input for ${operation}`, options);
this.userMessage = options?.userMessage;
}
}
/** Secret-safe correction metadata for one rejected caller argument. */
export interface AnalysisInputIssue {
readonly path: readonly (string | number)[];
readonly reason:
| "unknown_argument"
| "missing_argument"
| "invalid_type"
| "out_of_range"
| "invalid_value"
| "invalid_format";
/** Schema-authored correction guidance for cross-field or custom checks. */
readonly message?: string;
readonly expected?: JsonValue;
readonly minimum?: number;
readonly maximum?: number;
}
/** Provider output failed provider-neutral application parsing. */
export class AnalysisOutputError extends AnalysisError {
readonly _tag = "AnalysisOutputError";
constructor(
readonly operation: string,
readonly reason: string,
options?: AnalysisErrorOptions,
) {
super(`Invalid analysis output for ${operation}: ${reason}`, options);
}
}
/** Selected provider cannot execute a declared analysis operation. */
export class AnalysisCapabilityUnavailableError extends AnalysisError {
readonly _tag = "AnalysisCapabilityUnavailableError";
override readonly userMessage: string | undefined;
constructor(
readonly providerId: string,
readonly operation: string,
readonly reason: string,
options?: AnalysisErrorOptions & { readonly userMessage?: string },
) {
super(
`Provider ${providerId} cannot execute ${operation}: ${reason}`,
options,
);
this.userMessage = options?.userMessage;
}
}
/** Caller cancellation won before provider-neutral work completed. */
export class AnalysisCancelledError extends AnalysisError {
readonly _tag = "AnalysisCancelledError";
constructor(
readonly operation: string,
options?: AnalysisErrorOptions,
) {
super(`Analysis operation was cancelled: ${operation}`, options);
}
}
/** Provider-neutral operation exceeded its declared execution deadline. */
export class AnalysisTimeoutError extends AnalysisError {
readonly _tag = "AnalysisTimeoutError";
constructor(
readonly operation: string,
readonly timeoutMs: number,
options?: AnalysisErrorOptions,
) {
super(
`Analysis operation timed out after ${String(timeoutMs)}ms: ${operation}`,
options,
);
}
}
/** Host filesystem permissions denied the selected read; this is not malformed caller input. */
export class AnalysisAccessDeniedError extends AnalysisError {
readonly _tag = "AnalysisAccessDeniedError";
constructor(
readonly operation: string,
readonly path: string,
readonly systemCode: "EACCES" | "EPERM",
options?: AnalysisErrorOptions,
) {
super(
`Host filesystem read access denied (${systemCode}) for ${path} during ${operation}`,
options,
);
}
}
/** Selected artifact acquisition observed a change, so no stable identity can be reported. */
export class AnalysisArtifactChangedError extends AnalysisError {
readonly _tag = "AnalysisArtifactChangedError";
constructor(
readonly operation: string,
readonly path: string,
readonly reason: string,
options?: AnalysisErrorOptions,
) {
super(`Selected artifact changed during acquisition: ${reason}`, options);
}
}