diff --git a/packages/amazonq/.changes/next-release/Bug Fix-4f85fc73-11cd-4033-bc93-b49ff3c3e45e.json b/packages/amazonq/.changes/next-release/Bug Fix-4f85fc73-11cd-4033-bc93-b49ff3c3e45e.json new file mode 100644 index 00000000000..6684a90d129 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-4f85fc73-11cd-4033-bc93-b49ff3c3e45e.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Amazon Q /dev: Fix issue when files are deleted while preparing context" +} diff --git a/packages/core/src/amazonqFeatureDev/util/files.ts b/packages/core/src/amazonqFeatureDev/util/files.ts index 1b83bdbe2b5..8258d7fe179 100644 --- a/packages/core/src/amazonqFeatureDev/util/files.ts +++ b/packages/core/src/amazonqFeatureDev/util/files.ts @@ -13,7 +13,7 @@ import { getLogger } from '../../shared/logger/logger' import { maxFileSizeBytes } from '../limits' import { createHash } from 'crypto' import { CurrentWsFolders } from '../types' -import { ToolkitError } from '../../shared/errors' +import { hasCode, ToolkitError } from '../../shared/errors' import { AmazonqCreateUpload, Span, telemetry as amznTelemetry } from '../../shared/telemetry/telemetry' import { TelemetryHelper } from './telemetryHelper' import { maxRepoSizeBytes } from '../constants' @@ -39,7 +39,16 @@ export async function prepareRepoData( const ignoredExtensionMap = new Map() for (const file of files) { - const fileSize = (await fs.stat(file.fileUri)).size + let fileSize + try { + fileSize = (await fs.stat(file.fileUri)).size + } catch (error) { + if (hasCode(error) && error.code === 'ENOENT') { + // No-op: Skip if file does not exist + continue + } + throw error + } const isCodeFile_ = isCodeFile(file.relativeFilePath) if (fileSize >= maxFileSizeBytes || !isCodeFile_) { @@ -58,7 +67,17 @@ export async function prepareRepoData( totalBytes += fileSize const zipFolderPath = path.dirname(file.zipFilePath) - zip.addLocalFile(file.fileUri.fsPath, zipFolderPath) + + try { + zip.addLocalFile(file.fileUri.fsPath, zipFolderPath) + } catch (error) { + if (error instanceof Error && error.message.includes('File not found')) { + // No-op: Skip if file was deleted or does not exist + // Reference: https://github.com/cthackers/adm-zip/blob/1cd32f7e0ad3c540142a76609bb538a5cda2292f/adm-zip.js#L296-L321 + continue + } + throw error + } } const iterator = ignoredExtensionMap.entries() diff --git a/packages/core/src/shared/errors.ts b/packages/core/src/shared/errors.ts index 95cebb03111..54841b7622f 100644 --- a/packages/core/src/shared/errors.ts +++ b/packages/core/src/shared/errors.ts @@ -599,7 +599,7 @@ export function isAwsError(error: unknown): error is AWSError & { error_descript return error instanceof Error && hasCode(error) && hasTime(error) } -function hasCode(error: T): error is T & { code: string } { +export function hasCode(error: T): error is T & { code: string } { return typeof (error as { code?: unknown }).code === 'string' }