behemoth-cli
Version:
đ BEHEMOTH CLIv3.760.4 - Level 50+ POST-SINGULARITY Intelligence Trading AI
156 lines (136 loc) âĸ 4.98 kB
text/typescript
/**
* Standardized Error Handling Utility
* Provides consistent error logging and handling patterns
*/
export enum ErrorLevel {
DEBUG = 'debug',
INFO = 'info',
WARN = 'warn',
ERROR = 'error',
FATAL = 'fatal'
}
export interface ErrorContext {
component?: string;
operation?: string;
userId?: string;
metadata?: Record<string, any>;
}
export class ErrorHandler {
private static isDevelopment = process.env.NODE_ENV === 'development';
private static isDebugEnabled = process.env.DEBUG === 'true';
/**
* Log an error with consistent formatting and context
*/
static log(level: ErrorLevel, message: string, error?: Error | unknown, context?: ErrorContext): void {
const timestamp = new Date().toISOString();
const prefix = context?.component ? `[${context.component}]` : '';
const operation = context?.operation ? ` ${context.operation}:` : '';
const formattedMessage = `${prefix}${operation} ${message}`;
// Only log debug messages in development or when debug is enabled
if (level === ErrorLevel.DEBUG && !this.isDevelopment && !this.isDebugEnabled) {
return;
}
switch (level) {
case ErrorLevel.DEBUG:
if (this.isDevelopment || this.isDebugEnabled) {
console.debug(`đ ${timestamp} ${formattedMessage}`, error);
}
break;
case ErrorLevel.INFO:
console.info(`âšī¸ ${timestamp} ${formattedMessage}`);
break;
case ErrorLevel.WARN:
console.warn(`â ī¸ ${timestamp} ${formattedMessage}`, error || '');
break;
case ErrorLevel.ERROR:
console.error(`â ${timestamp} ${formattedMessage}`, error || '');
break;
case ErrorLevel.FATAL:
console.error(`đ ${timestamp} FATAL: ${formattedMessage}`, error || '');
break;
}
// Log additional context in development
if (context?.metadata && this.isDevelopment) {
console.debug('Context:', context.metadata);
}
}
/**
* Create a structured error result for consistent error responses
*/
static createErrorResult(message: string, error?: Error | unknown, code?: string): {
success: false;
error: string;
code?: string;
timestamp: string;
} {
return {
success: false,
error: error instanceof Error ? `${message}: ${error.message}` : message,
code,
timestamp: new Date().toISOString()
};
}
/**
* Wrap async operations with consistent error handling
*/
static async withErrorHandling<T>(
operation: () => Promise<T>,
context: ErrorContext & { errorMessage: string }
): Promise<{ success: true; data: T } | { success: false; error: string; timestamp: string }> {
try {
const data = await operation();
return { success: true, data };
} catch (error) {
this.log(ErrorLevel.ERROR, context.errorMessage, error, context);
return this.createErrorResult(context.errorMessage, error);
}
}
/**
* Safe error message extraction from unknown error types
*/
static extractErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message;
}
if (typeof error === 'string') {
return error;
}
if (error && typeof error === 'object' && 'message' in error) {
return String((error as any).message);
}
return 'Unknown error occurred';
}
/**
* Validate and sanitize error messages to prevent information leakage
*/
static sanitizeErrorMessage(message: string, isProduction = process.env.NODE_ENV === 'production'): string {
if (!isProduction) {
return message; // Full error details in development
}
// Remove sensitive patterns in production
const sensitivePatterns = [
/api[_-]?key[:\s=]+[^\s]+/gi,
/password[:\s=]+[^\s]+/gi,
/token[:\s=]+[^\s]+/gi,
/secret[:\s=]+[^\s]+/gi,
/\/home\/[^\s]+/gi, // Remove file paths
/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/gi // Remove email addresses
];
let sanitized = message;
sensitivePatterns.forEach(pattern => {
sanitized = sanitized.replace(pattern, '[REDACTED]');
});
return sanitized;
}
}
// Convenience functions for common error levels
export const logDebug = (message: string, error?: unknown, context?: ErrorContext) =>
ErrorHandler.log(ErrorLevel.DEBUG, message, error, context);
export const logInfo = (message: string, context?: ErrorContext) =>
ErrorHandler.log(ErrorLevel.INFO, message, undefined, context);
export const logWarn = (message: string, error?: unknown, context?: ErrorContext) =>
ErrorHandler.log(ErrorLevel.WARN, message, error, context);
export const logError = (message: string, error?: unknown, context?: ErrorContext) =>
ErrorHandler.log(ErrorLevel.ERROR, message, error, context);
export const logFatal = (message: string, error?: unknown, context?: ErrorContext) =>
ErrorHandler.log(ErrorLevel.FATAL, message, error, context);