/** * Centralized error handling utility for TSPM */ // Define error types export enum ErrorType { CONFIG = 'ConfigError', PROCESS = 'ProcessError', RUNTIME = 'RuntimeError', VALIDATION = 'ValidationError', UNKNOWN = 'UnknownError' } // Base error class with type and code support export class TspmError extends Error { type: ErrorType; code: string; details?: Record; constructor( message: string, type: ErrorType = ErrorType.UNKNOWN, code: string = 'ERR_UNKNOWN', details?: Record ) { super(message); this.name = type; this.type = type; this.code = code; this.details = details; // Preserve proper stack trace if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } toString(): string { return `[${this.type}:${this.code}] ${this.message}`; } } // Specific error classes export class ConfigError extends TspmError { constructor(message: string, code: string = 'ERR_CONFIG', details?: Record) { super(message, ErrorType.CONFIG, code, details); } } export class ProcessError extends TspmError { constructor(message: string, code: string = 'ERR_PROCESS', details?: Record) { super(message, ErrorType.PROCESS, code, details); } } export class ValidationError extends TspmError { constructor(message: string, code: string = 'ERR_VALIDATION', details?: Record) { super(message, ErrorType.VALIDATION, code, details); } } // Utility for handling any error type export const handleError = (error: Error | unknown): TspmError => { if (error instanceof TspmError) { return error; } if (error instanceof Error) { return new TspmError(error.message, ErrorType.UNKNOWN, 'ERR_UNKNOWN', { originalError: error }); } return new TspmError(String(error), ErrorType.UNKNOWN, 'ERR_UNKNOWN'); }; // Logger with different log levels export enum LogLevel { DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, NONE = 4 } export class Logger { private static instance: Logger; private level: LogLevel = LogLevel.INFO; private componentName: string; constructor(componentName: string) { this.componentName = componentName; } static getInstance(componentName: string): Logger { if (!Logger.instance) { Logger.instance = new Logger(componentName); } return Logger.instance; } setLevel(level: LogLevel): void { this.level = level; } private formatMessage(message: string): string { const timestamp = new Date().toISOString(); return `[${timestamp}] [${this.componentName}] ${message}`; } debug(message: string): void { if (this.level <= LogLevel.DEBUG) { console.log(this.formatMessage(`DEBUG: ${message}`)); } } info(message: string): void { if (this.level <= LogLevel.INFO) { console.log(this.formatMessage(message)); } } warn(message: string): void { if (this.level <= LogLevel.WARN) { console.warn(this.formatMessage(`WARNING: ${message}`)); } } error(error: Error | unknown): void { if (this.level <= LogLevel.ERROR) { const tspmError = handleError(error); console.error(this.formatMessage(`ERROR: ${tspmError.toString()}`)); // In debug mode, also log stack trace if (this.level === LogLevel.DEBUG && tspmError.stack) { console.error(tspmError.stack); } } } }