Merge branch 'feat/error-hierarchy'
This commit is contained in:
@@ -1 +1,125 @@
|
||||
export {};
|
||||
type CallStatus = "pending" | "running" | "completed" | "failed" | "aborted";
|
||||
|
||||
class FlowgraphError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "FlowgraphError";
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructionError extends FlowgraphError {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "ConstructionError";
|
||||
}
|
||||
}
|
||||
|
||||
class DuplicateNodeError extends ConstructionError {
|
||||
readonly key: string;
|
||||
constructor(key: string) {
|
||||
super(`Node with key "${key}" already exists`);
|
||||
this.name = "DuplicateNodeError";
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
class DuplicateEdgeError extends ConstructionError {
|
||||
readonly source: string;
|
||||
readonly target: string;
|
||||
constructor(source: string, target: string) {
|
||||
super(`Edge "${source} -> ${target}" already exists`);
|
||||
this.name = "DuplicateEdgeError";
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
}
|
||||
}
|
||||
|
||||
class NodeNotFoundError extends ConstructionError {
|
||||
readonly key: string;
|
||||
constructor(key: string) {
|
||||
super(`Node "${key}" not found in graph`);
|
||||
this.name = "NodeNotFoundError";
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
class CycleError extends ConstructionError {
|
||||
readonly cycles: string[][];
|
||||
constructor(cycles: string[][]) {
|
||||
super(`Adding this edge would create a cycle: ${JSON.stringify(cycles)}`);
|
||||
this.name = "CycleError";
|
||||
this.cycles = cycles;
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidInputError extends ConstructionError {
|
||||
readonly errors: ValidationError[];
|
||||
constructor(errors: ValidationError[]) {
|
||||
super(`Invalid input: ${errors.length} validation error(s)`);
|
||||
this.name = "InvalidInputError";
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidTransitionError extends FlowgraphError {
|
||||
readonly requestId: string;
|
||||
readonly from: CallStatus;
|
||||
readonly to: CallStatus;
|
||||
constructor(requestId: string, from: CallStatus, to: CallStatus) {
|
||||
super(`Invalid status transition for call ${requestId}: ${from} → ${to}`);
|
||||
this.name = "InvalidTransitionError";
|
||||
this.requestId = requestId;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
}
|
||||
|
||||
interface ValidationError {
|
||||
type: "schema";
|
||||
nodeKey: string;
|
||||
field: string;
|
||||
message: string;
|
||||
value?: unknown;
|
||||
}
|
||||
|
||||
interface GraphValidationError {
|
||||
type: "graph";
|
||||
category: "cycle" | "dangling-reference" | "orphan-node" | "status-inconsistency";
|
||||
details: unknown;
|
||||
}
|
||||
|
||||
interface TypeMismatch {
|
||||
path: string;
|
||||
expected: string;
|
||||
actual: string;
|
||||
}
|
||||
|
||||
interface TypeIncompatError {
|
||||
type: "type-compat";
|
||||
sourceKey: string;
|
||||
targetKey: string;
|
||||
compatible: false;
|
||||
mismatches: TypeMismatch[];
|
||||
}
|
||||
|
||||
type AnyValidationError = ValidationError | GraphValidationError | TypeIncompatError;
|
||||
|
||||
export {
|
||||
FlowgraphError,
|
||||
ConstructionError,
|
||||
DuplicateNodeError,
|
||||
DuplicateEdgeError,
|
||||
NodeNotFoundError,
|
||||
CycleError,
|
||||
InvalidInputError,
|
||||
InvalidTransitionError,
|
||||
};
|
||||
|
||||
export type {
|
||||
CallStatus,
|
||||
ValidationError,
|
||||
GraphValidationError,
|
||||
TypeMismatch,
|
||||
TypeIncompatError,
|
||||
AnyValidationError,
|
||||
};
|
||||
@@ -1 +1 @@
|
||||
export {};
|
||||
export * from "./error/index.js";
|
||||
Reference in New Issue
Block a user