smart-dropzone-react
Version:
🚀 A production-ready React dropzone component with smart defaults, drag & drop reordering, chunked uploads, resume functionality, and comprehensive provider support (Cloudinary, AWS S3, Supabase)
1 lines • 15 kB
Source Map (JSON)
{"version":3,"sources":["../src/core/error-handler.ts"],"names":["UploadError","_UploadError","code","userMessage","technicalMessage","context","retryable","__publicField","message","fileName","fileId","provider","_ErrorBoundary","error","errorMessage","pattern","enhancedContext","enhancedError","stats","limit","attemptCount","UPLOAD","TIMING","ErrorBoundary"],"mappings":"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","file":"chunk-BRPMGXDP.cjs","sourcesContent":["import { TIMING, UPLOAD } from \"./config\";\r\n\r\nexport interface ErrorContext {\r\n operation: \"validation\" | \"upload\" | \"processing\" | \"network\" | \"provider\";\r\n fileId?: string;\r\n fileName?: string;\r\n provider?: string;\r\n details?: Record<string, any>;\r\n correlationId?: string;\r\n userAgent?: string;\r\n sessionId?: string;\r\n}\r\n\r\nexport class UploadError extends Error {\r\n public readonly code: string;\r\n public readonly context: ErrorContext;\r\n public readonly userMessage: string;\r\n public readonly technicalMessage: string;\r\n public readonly timestamp: Date;\r\n public readonly retryable: boolean;\r\n\r\n constructor(\r\n code: string,\r\n userMessage: string,\r\n technicalMessage: string,\r\n context: ErrorContext,\r\n retryable: boolean = false\r\n ) {\r\n super(userMessage);\r\n this.name = \"UploadError\";\r\n this.code = code;\r\n this.context = context;\r\n this.userMessage = userMessage;\r\n this.technicalMessage = technicalMessage;\r\n this.timestamp = new Date();\r\n this.retryable = retryable;\r\n }\r\n\r\n static validationError(message: string, fileName?: string): UploadError {\r\n return new UploadError(\r\n \"VALIDATION_ERROR\",\r\n message,\r\n `File validation failed: ${message}`,\r\n { operation: \"validation\", fileName },\r\n false\r\n );\r\n }\r\n\r\n static uploadError(\r\n message: string,\r\n fileId: string,\r\n fileName?: string\r\n ): UploadError {\r\n return new UploadError(\r\n \"UPLOAD_ERROR\",\r\n message,\r\n `Upload failed for file ${fileName || fileId}: ${message}`,\r\n { operation: \"upload\", fileId, fileName },\r\n true\r\n );\r\n }\r\n\r\n static networkError(message: string, fileId?: string): UploadError {\r\n return new UploadError(\r\n \"NETWORK_ERROR\",\r\n \"Network connection issue. Please check your internet connection and try again.\",\r\n `Network error: ${message}`,\r\n { operation: \"network\", fileId },\r\n true\r\n );\r\n }\r\n\r\n static providerError(\r\n message: string,\r\n provider: string,\r\n fileId?: string\r\n ): UploadError {\r\n return new UploadError(\r\n \"PROVIDER_ERROR\",\r\n `Service temporarily unavailable. Please try again later.`,\r\n `Provider ${provider} error: ${message}`,\r\n { operation: \"provider\", provider, fileId },\r\n true\r\n );\r\n }\r\n\r\n static processingError(message: string, fileId?: string): UploadError {\r\n return new UploadError(\r\n \"PROCESSING_ERROR\",\r\n \"File processing failed. Please try a different file.\",\r\n `Processing error: ${message}`,\r\n { operation: \"processing\", fileId },\r\n false\r\n );\r\n }\r\n\r\n toJSON() {\r\n return {\r\n code: this.code,\r\n userMessage: this.userMessage,\r\n technicalMessage: this.technicalMessage,\r\n context: this.context,\r\n timestamp: this.timestamp.toISOString(),\r\n retryable: this.retryable,\r\n stack: this.stack,\r\n };\r\n }\r\n}\r\n\r\nexport class ErrorBoundary {\r\n private static readonly errorMap = new Map<string, string>([\r\n [\"FILE_TOO_LARGE\", \"File is too large. Please choose a smaller file.\"],\r\n [\r\n \"INVALID_FILE_TYPE\",\r\n \"File type not supported. Please choose a different file.\",\r\n ],\r\n [\r\n \"TOO_MANY_FILES\",\r\n \"Too many files selected. Please reduce the number of files.\",\r\n ],\r\n [\r\n \"NETWORK_TIMEOUT\",\r\n \"Upload timed out. Please check your connection and try again.\",\r\n ],\r\n [\r\n \"QUOTA_EXCEEDED\",\r\n \"Storage quota exceeded. Please remove some files and try again.\",\r\n ],\r\n [\r\n \"FILE_CORRUPTED\",\r\n \"File appears to be corrupted. Please try a different file.\",\r\n ],\r\n [\"UPLOAD_CANCELLED\", \"Upload was cancelled.\"],\r\n [\r\n \"PROVIDER_UNAVAILABLE\",\r\n \"Upload service is temporarily unavailable. Please try again later.\",\r\n ],\r\n ]);\r\n\r\n private static errorLogs: UploadError[] = [];\r\n private static maxLogSize: number = 100;\r\n private static sessionId: string = this.generateSessionId();\r\n\r\n static getUserMessage(error: Error | UploadError): string {\r\n if (error instanceof UploadError) {\r\n return error.userMessage;\r\n }\r\n\r\n // Map common error messages to user-friendly versions\r\n const errorMessage = error.message.toLowerCase();\r\n\r\n for (const [code, userMessage] of this.errorMap) {\r\n if (\r\n errorMessage.includes(code.toLowerCase()) ||\r\n errorMessage.includes(code.replace(\"_\", \" \").toLowerCase())\r\n ) {\r\n return userMessage;\r\n }\r\n }\r\n\r\n // Default user-friendly message\r\n return \"Something went wrong. Please try again.\";\r\n }\r\n\r\n static isRetryable(error: Error | UploadError): boolean {\r\n if (error instanceof UploadError) {\r\n return error.retryable;\r\n }\r\n\r\n // Determine if error is retryable based on message\r\n const errorMessage = error.message.toLowerCase();\r\n const retryablePatterns = [\r\n \"network\",\r\n \"timeout\",\r\n \"connection\",\r\n \"server error\",\r\n \"temporary\",\r\n \"rate limit\",\r\n ];\r\n\r\n return retryablePatterns.some((pattern) => errorMessage.includes(pattern));\r\n }\r\n\r\n static getErrorCode(error: Error | UploadError): string {\r\n if (error instanceof UploadError) {\r\n return error.code;\r\n }\r\n\r\n // Infer error code from message\r\n const errorMessage = error.message.toLowerCase();\r\n\r\n if (\r\n errorMessage.includes(\"network\") ||\r\n errorMessage.includes(\"connection\")\r\n ) {\r\n return \"NETWORK_ERROR\";\r\n }\r\n if (errorMessage.includes(\"timeout\")) {\r\n return \"TIMEOUT_ERROR\";\r\n }\r\n if (errorMessage.includes(\"validation\")) {\r\n return \"VALIDATION_ERROR\";\r\n }\r\n\r\n return \"UNKNOWN_ERROR\";\r\n }\r\n\r\n static logError(error: UploadError): void {\r\n // Enhance context with additional tracking information\r\n const enhancedContext = {\r\n ...error.context,\r\n correlationId:\r\n error.context.correlationId || this.generateCorrelationId(),\r\n sessionId: this.sessionId,\r\n userAgent:\r\n typeof navigator !== \"undefined\" ? navigator.userAgent : \"unknown\",\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n // Create a new UploadError with enhanced context\r\n const enhancedError = new UploadError(\r\n error.code,\r\n error.userMessage,\r\n error.technicalMessage,\r\n enhancedContext,\r\n error.retryable\r\n );\r\n\r\n // Add to internal log\r\n this.errorLogs.push(enhancedError);\r\n\r\n // Maintain log size limit\r\n if (this.errorLogs.length > this.maxLogSize) {\r\n this.errorLogs.shift();\r\n }\r\n\r\n // Log to console in development\r\n if (process.env.NODE_ENV === \"development\") {\r\n console.error(\"SmartDropzone Error:\", enhancedError);\r\n }\r\n\r\n // In production, you could send to error tracking service\r\n // this.sendToErrorService(enhancedError);\r\n }\r\n\r\n static getErrorStats(): {\r\n total: number;\r\n byOperation: Record<string, number>;\r\n byCode: Record<string, number>;\r\n retryableCount: number;\r\n } {\r\n const stats = {\r\n total: this.errorLogs.length,\r\n byOperation: {} as Record<string, number>,\r\n byCode: {} as Record<string, number>,\r\n retryableCount: 0,\r\n };\r\n\r\n this.errorLogs.forEach((error) => {\r\n // Count by operation\r\n stats.byOperation[error.context.operation] =\r\n (stats.byOperation[error.context.operation] || 0) + 1;\r\n\r\n // Count by code\r\n stats.byCode[error.code] = (stats.byCode[error.code] || 0) + 1;\r\n\r\n // Count retryable errors\r\n if (error.retryable) {\r\n stats.retryableCount++;\r\n }\r\n });\r\n\r\n return stats;\r\n }\r\n\r\n static clearErrorLogs(): void {\r\n this.errorLogs = [];\r\n }\r\n\r\n static getRecentErrors(limit: number = 10): UploadError[] {\r\n return this.errorLogs.slice(-limit);\r\n }\r\n\r\n static shouldRetry(\r\n error: Error | UploadError,\r\n attemptCount: number\r\n ): boolean {\r\n if (attemptCount >= UPLOAD.MAX_RETRY_ATTEMPTS) {\r\n return false;\r\n }\r\n\r\n return this.isRetryable(error);\r\n }\r\n\r\n static getRetryDelay(attemptCount: number): number {\r\n return (\r\n TIMING.RETRY_DELAY * Math.pow(TIMING.RETRY_EXPONENTIAL_BASE, attemptCount)\r\n );\r\n }\r\n\r\n private static generateSessionId(): string {\r\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n\r\n private static generateCorrelationId(): string {\r\n return `corr-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n\r\n // Optional: Send errors to external service\r\n // private static sendToErrorService(error: UploadError): void {\r\n // // Implementation for sending to error tracking service\r\n // // (Sentry, LogRocket, etc.)\r\n // }\r\n}\r\n"]}