diff --git a/apps/app/src/actions/files/upload-file.ts b/apps/app/src/actions/files/upload-file.ts index f3a0ecbe1..d20b46d2c 100644 --- a/apps/app/src/actions/files/upload-file.ts +++ b/apps/app/src/actions/files/upload-file.ts @@ -42,6 +42,23 @@ const uploadAttachmentSchema = z.object({ export const uploadFile = async (input: z.infer) => { logger.info(`[uploadFile] Starting upload for ${input.fileName}`); try { + // Check if S3 client is available + if (!s3Client) { + logger.error('[uploadFile] S3 client not initialized - check environment variables'); + return { + success: false, + error: 'File upload service is currently unavailable. Please contact support.', + } as const; + } + + if (!BUCKET_NAME) { + logger.error('[uploadFile] S3 bucket name not configured'); + return { + success: false, + error: 'File upload service is not properly configured.', + } as const; + } + const { fileName, fileType, fileData, entityId, entityType, pathToRevalidate } = uploadAttachmentSchema.parse(input); @@ -49,7 +66,11 @@ export const uploadFile = async (input: z.infer) const organizationId = session?.session.activeOrganizationId; if (!organizationId) { - throw new Error('Not authorized - no organization found'); + logger.error('[uploadFile] Not authorized - no organization found'); + return { + success: false, + error: 'Not authorized - no organization found', + } as const; } logger.info(`[uploadFile] Starting upload for ${fileName} in org ${organizationId}`); @@ -59,7 +80,13 @@ export const uploadFile = async (input: z.infer) const MAX_FILE_SIZE_MB = 10; const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024; if (fileBuffer.length > MAX_FILE_SIZE_BYTES) { - throw new Error(`File exceeds the ${MAX_FILE_SIZE_MB}MB limit.`); + logger.warn( + `[uploadFile] File size ${fileBuffer.length} exceeds the ${MAX_FILE_SIZE_MB}MB limit.`, + ); + return { + success: false, + error: `File exceeds the ${MAX_FILE_SIZE_MB}MB limit.`, + } as const; } const timestamp = Date.now(); diff --git a/apps/app/src/app/s3.ts b/apps/app/src/app/s3.ts index 749c29401..fd6ddb3d2 100644 --- a/apps/app/src/app/s3.ts +++ b/apps/app/src/app/s3.ts @@ -14,10 +14,21 @@ const redact = (value?: string) => { }; try { + console.log('[S3] Initializing S3 Client'); + console.error('--- Provided Configuration ---'); + console.error(`APP_AWS_REGION: ${APP_AWS_REGION}`); + console.error(`APP_AWS_ACCESS_KEY_ID: ${redact(APP_AWS_ACCESS_KEY_ID)}`); + console.error(`APP_AWS_SECRET_ACCESS_KEY: ${redact(APP_AWS_SECRET_ACCESS_KEY)}`); + console.error(`APP_AWS_BUCKET_NAME: ${BUCKET_NAME}`); + console.error('-----------------------------'); + if (!APP_AWS_ACCESS_KEY_ID || !APP_AWS_SECRET_ACCESS_KEY || !BUCKET_NAME || !APP_AWS_REGION) { + console.error('[S3] AWS S3 credentials or configuration missing. Check environment variables.'); throw new Error('AWS S3 credentials or configuration missing. Check environment variables.'); } + console.log('[S3] AWS S3 credentials or configuration found. Initializing S3 Client'); + s3ClientInstance = new S3Client({ region: APP_AWS_REGION, credentials: { @@ -25,22 +36,20 @@ try { secretAccessKey: APP_AWS_SECRET_ACCESS_KEY, }, }); + + console.log('[S3] S3 Client initialized successfully'); } catch (error) { console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); console.error('!!! FAILED TO INITIALIZE S3 CLIENT !!!'); console.error('!!! This is likely due to missing or invalid environment variables. !!!'); - console.error('--- Provided Configuration ---'); - console.error(`APP_AWS_REGION: ${APP_AWS_REGION}`); - console.error(`APP_AWS_ACCESS_KEY_ID: ${redact(APP_AWS_ACCESS_KEY_ID)}`); - console.error(`APP_AWS_SECRET_ACCESS_KEY: ${redact(APP_AWS_SECRET_ACCESS_KEY)}`); - console.error(`APP_AWS_BUCKET_NAME: ${BUCKET_NAME}`); - console.error('-----------------------------'); console.error('Error:', error); console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); - // Prevent the app from continuing without a valid S3 client - // In a real-world scenario, you might have a fallback or a dummy client. - // For now, we re-throw to make the crash explicit. - throw error; + + // Create a dummy client that will fail gracefully at runtime instead of crashing during initialization + s3ClientInstance = null as any; + console.error( + '[S3] Creating dummy S3 client - file uploads will fail until credentials are fixed', + ); } export const s3Client = s3ClientInstance;