LetsTryGPT/agent4-implementation
0
1/**2 * Centralized error handling utilities3 * Consolidates duplicate error handling patterns across the codebase4 */5 6export class ErrorHandler {7 /**8 * Formats any error type into a standard Error object with message9 * @param error - The error to format (can be Error, string, or unknown)10 * @param context - Context string to prefix the error message11 * @returns Formatted Error object12 */13 static format(error: unknown, context?: string): Error {14 const message = error instanceof Error ? error.message : String(error || 'Unknown error');15 const prefix = context ? `${context}: ` : '';16 return error instanceof Error17 ? new Error(`${prefix}${message}`)18 : new Error(`${prefix}${message}`);19 }20 21 /**22 * Extracts error message from any error type23 * @param error - The error to extract message from24 * @returns Error message string25 */26 static getMessage(error: unknown): string {27 if (error instanceof Error) {28 return error.message;29 }30 if (typeof error === 'string') {31 return error;32 }33 if (error && typeof error === 'object' && 'message' in error) {34 return String(error.message);35 }36 return 'Unknown error';37 }38 39 /**40 * Logs error and throws formatted error41 * @param error - The error to log and throw42 * @param context - Context for the error43 * @param logger - Optional logger function (defaults to console.error)44 * @throws {Error} Always throws the formatted error45 */46 static logAndThrow(47 error: unknown,48 context: string,49 logger: (message: string, ...args: unknown[]) => void = console.error50 ): never {51 const message = this.getMessage(error);52 logger(`Error in ${context}:`, message);53 throw this.format(error, context);54 }55 56 /**57 * Converts error to HTTP response format58 * @param error - The error to convert59 * @param isDevelopment - Whether in development mode (shows details)60 * @returns Error response object61 */62 static toResponse(error: unknown, isDevelopment: boolean = false): ErrorResponse {63 const message = this.getMessage(error);64 65 if (!isDevelopment) {66 return {67 success: false,68 error: 'An error occurred while processing your request',69 };70 }71 72 return {73 success: false,74 error: message,75 details:76 error instanceof Error ? [{ field: 'execution', message: error.message }] : undefined,77 };78 }79 80 /**81 * Checks if error is retryable (network errors, timeouts, rate limits)82 * @param error - The error to check83 * @returns True if error is retryable84 */85 static isRetryable(error: unknown): boolean {86 if (!error || typeof error !== 'object') {87 return false;88 }89 90 const err = error as any;91 92 // Check HTTP status codes93 if (err.response?.status) {94 const status = err.response.status;95 // Retry on: 408 (Timeout), 429 (Rate Limit), 500+ (Server Errors), 503 (Service Unavailable)96 return status === 408 || status === 429 || status >= 500;97 }98 99 // Check error codes100 if (err.code) {101 const retryableCodes = [102 'ETIMEDOUT',103 'ECONNRESET',104 'ECONNREFUSED',105 'ENOTFOUND',106 'ENETUNREACH',107 'EAI_AGAIN',108 ];109 return retryableCodes.includes(err.code);110 }111 112 // Check error messages113 if (err.message) {114 const message = err.message.toLowerCase();115 return (116 message.includes('timeout') ||117 message.includes('rate limit') ||118 message.includes('too many requests') ||119 message.includes('service unavailable') ||120 message.includes('connection') ||121 message.includes('network')122 );123 }124 125 return false;126 }127 128 /**129 * Wraps async function with error handling130 * @param fn - Async function to wrap131 * @param context - Context for errors132 * @returns Wrapped function133 */134 static wrapAsync<T extends (...args: any[]) => Promise<any>>(fn: T, context: string): T {135 return (async (...args: Parameters<T>): Promise<ReturnType<T>> => {136 try {137 return await fn(...args);138 } catch (error) {139 throw this.format(error, context);140 }141 }) as T;142 }143}144 145/**146 * Error response interface147 */148export interface ErrorResponse {149 success: false;150 error: string;151 details?: Array<{152 field: string;153 message: string;154 }>;155}156 157/**158 * Custom error types for better error handling159 */160export class ValidationError extends Error {161 constructor(162 message: string,163 public field?: string164 ) {165 super(message);166 this.name = 'ValidationError';167 }168}169 170export class AuthenticationError extends Error {171 constructor(message: string = 'Authentication failed') {172 super(message);173 this.name = 'AuthenticationError';174 }175}176 177export class RateLimitError extends Error {178 constructor(message: string = 'Rate limit exceeded') {179 super(message);180 this.name = 'RateLimitError';181 }182}183 184export class ProviderError extends Error {185 constructor(186 message: string,187 public provider: string,188 public originalError?: Error189 ) {190 super(message);191 this.name = 'ProviderError';192 }193}194 