@zhanghongping/json-sage-workflow-cli
Version:
An intelligent JSON processing workflow system with improved error handling and configuration
128 lines (113 loc) • 3.18 kB
text/typescript
import { WorkflowContext } from './WorkflowContext';
import { NodeUtils, AsyncUtils } from '../utils/NodeUtils';
import { NodeError } from './errors/NodeError';
/**
* Abstract base class for all workflow nodes
*/
export abstract class BaseNode {
protected id: string;
protected config: any;
protected timeout: number = 30000; // Default timeout: 30 seconds
/**
* Creates a new node instance
* @param config - Node configuration
*/
constructor(config?: any) {
if (config) {
NodeUtils.validateConfig(config);
this.config = config;
}
}
/**
* Sets the node ID
* @param id - Node identifier
*/
setId(id: string): void {
this.id = id;
}
/**
* Gets the node ID
* @returns Node identifier
*/
getId(): string {
return this.id;
}
/**
* Sets node configuration
* @param config - Node configuration
*/
setConfig(config: any): void {
NodeUtils.validateConfig(config);
this.config = config;
}
/**
* Gets node configuration
* @returns Node configuration
*/
getConfig(): any {
return this.config;
}
/**
* Sets operation timeout
* @param timeout - Timeout in milliseconds
*/
setTimeout(timeout: number): void {
this.timeout = timeout;
}
/**
* Executes the node's main logic
* @param context - Workflow context
*/
async execute(context: WorkflowContext): Promise<void> {
try {
// Validate input
const input = context.getData('input');
await NodeUtils.validateInput(input, this.config?.schema, context);
// Execute with timeout
await AsyncUtils.withTimeout(
async () => await this.processNode(context),
this.timeout
);
} catch (error) {
await this.handleError(error as Error, context);
}
}
/**
* Validates node state and configuration
* @param context - Workflow context
* @returns true if validation passes
*/
async validate(context: WorkflowContext): Promise<boolean> {
const input = context.getData('input');
await NodeUtils.validateInput(input, this.config?.schema, context);
return true;
}
/**
* Cleans up node resources
* @param context - Workflow context
*/
async cleanup(context: WorkflowContext): Promise<void> {
// Default implementation - override if needed
}
/**
* Handles node errors
* @param error - Error that occurred
* @param context - Workflow context
*/
async handleError(error: Error, context: WorkflowContext): Promise<void> {
context.log.error(`Error in node ${this.id}:`, error);
if (this.config?.errorHandler) {
await this.config.errorHandler(error, context);
} else {
throw new NodeError(`Node ${this.id} execution failed: ${error.message}`, {
cause: error,
nodeId: this.id
});
}
}
/**
* Main node processing logic - must be implemented by concrete nodes
* @param context - Workflow context
*/
protected abstract processNode(context: WorkflowContext): Promise<void>;
}