138 lines
3.4 KiB
TypeScript
138 lines
3.4 KiB
TypeScript
/**
|
|
* 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<string, any>;
|
|
|
|
constructor(
|
|
message: string,
|
|
type: ErrorType = ErrorType.UNKNOWN,
|
|
code: string = 'ERR_UNKNOWN',
|
|
details?: Record<string, any>
|
|
) {
|
|
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<string, any>) {
|
|
super(message, ErrorType.CONFIG, code, details);
|
|
}
|
|
}
|
|
|
|
export class ProcessError extends TspmError {
|
|
constructor(message: string, code: string = 'ERR_PROCESS', details?: Record<string, any>) {
|
|
super(message, ErrorType.PROCESS, code, details);
|
|
}
|
|
}
|
|
|
|
export class ValidationError extends TspmError {
|
|
constructor(message: string, code: string = 'ERR_VALIDATION', details?: Record<string, any>) {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
} |