From 60b342bafea187c90e78475024f0884558bc57e4 Mon Sep 17 00:00:00 2001 From: Kevin Ding Date: Mon, 24 Feb 2025 15:45:53 -0500 Subject: [PATCH 1/2] fix(amazonq): fix uploading file method error handling for /doc --- ...-6b8cf110-2050-4ac1-8a3b-637ed54980cf.json | 4 ++ packages/core/src/amazonq/errors.ts | 13 ++++++ packages/core/src/amazonq/util/files.ts | 5 ++- .../core/src/amazonqDoc/session/session.ts | 45 +++++++++++-------- .../src/amazonqFeatureDev/session/session.ts | 42 ++++++++++------- 5 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-6b8cf110-2050-4ac1-8a3b-637ed54980cf.json create mode 100644 packages/core/src/amazonq/errors.ts diff --git a/packages/amazonq/.changes/next-release/Bug Fix-6b8cf110-2050-4ac1-8a3b-637ed54980cf.json b/packages/amazonq/.changes/next-release/Bug Fix-6b8cf110-2050-4ac1-8a3b-637ed54980cf.json new file mode 100644 index 00000000000..011b5eb6c62 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-6b8cf110-2050-4ac1-8a3b-637ed54980cf.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Amazon Q /doc: Fix uploading file method throwing incorrect workspace too large error message" +} diff --git a/packages/core/src/amazonq/errors.ts b/packages/core/src/amazonq/errors.ts new file mode 100644 index 00000000000..cf45cb61265 --- /dev/null +++ b/packages/core/src/amazonq/errors.ts @@ -0,0 +1,13 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + */ + +import { ToolkitError } from '../shared/errors' + +export class CommonAmazonQContentLengthError extends ToolkitError { + constructor(message: string) { + super(message, { code: 'CommonAmazonQContentLengthError' }) + } +} diff --git a/packages/core/src/amazonq/util/files.ts b/packages/core/src/amazonq/util/files.ts index 848e6c5d807..eef133c514f 100644 --- a/packages/core/src/amazonq/util/files.ts +++ b/packages/core/src/amazonq/util/files.ts @@ -12,7 +12,7 @@ import { getWorkspaceFoldersByPrefixes, } from '../../shared/utilities/workspaceUtils' -import { ContentLengthError, PrepareRepoFailedError } from '../../amazonqFeatureDev/errors' +import { PrepareRepoFailedError } from '../../amazonqFeatureDev/errors' import { getLogger } from '../../shared/logger/logger' import { maxFileSizeBytes } from '../../amazonqFeatureDev/limits' import { CurrentWsFolders, DeletedFileInfo, NewFileInfo, NewFileZipContents } from '../../amazonqDoc/types' @@ -28,6 +28,7 @@ import { ZipStream } from '../../shared/utilities/zipStream' import { isPresent } from '../../shared/utilities/collectionUtils' import { AuthUtil } from '../../codewhisperer/util/authUtil' import { TelemetryHelper } from '../util/telemetryHelper' +import { CommonAmazonQContentLengthError } from '../errors' export const SvgFileExtension = '.svg' @@ -186,7 +187,7 @@ export async function prepareRepoData( } catch (error) { getLogger().debug(`featureDev: Failed to prepare repo: ${error}`) if (error instanceof ToolkitError && error.code === 'ContentLengthError') { - throw new ContentLengthError() + throw new CommonAmazonQContentLengthError(error.message) } throw new PrepareRepoFailedError() } diff --git a/packages/core/src/amazonqDoc/session/session.ts b/packages/core/src/amazonqDoc/session/session.ts index f132799d8ae..73f725118ea 100644 --- a/packages/core/src/amazonqDoc/session/session.ts +++ b/packages/core/src/amazonqDoc/session/session.ts @@ -30,6 +30,8 @@ import fs from '../../shared/fs/fs' import globals from '../../shared/extensionGlobals' import { extensionVersion } from '../../shared/vscode/env' import { getLogger } from '../../shared/logger/logger' +import { ContentLengthError } from '../errors' +import { CommonAmazonQContentLengthError } from '../../amazonq/errors' export class Session { private _state?: SessionState | Omit @@ -126,28 +128,35 @@ export class Session { return this.nextInteraction(msg, mode, folderPath) } private async nextInteraction(msg: string, mode: Mode, folderPath?: string) { - const resp = await this.state.interact({ - task: this.task, - msg, - fs: this.config.fs, - mode: mode, - folderPath: folderPath, - messenger: this.messenger, - telemetry: this.telemetry, - tokenSource: this.state.tokenSource, - uploadHistory: this.state.uploadHistory, - }) + try { + const resp = await this.state.interact({ + task: this.task, + msg, + fs: this.config.fs, + mode: mode, + folderPath: folderPath, + messenger: this.messenger, + telemetry: this.telemetry, + tokenSource: this.state.tokenSource, + uploadHistory: this.state.uploadHistory, + }) + + if (resp.nextState) { + if (!this.state?.tokenSource?.token.isCancellationRequested) { + this.state?.tokenSource?.cancel() + } - if (resp.nextState) { - if (!this.state?.tokenSource?.token.isCancellationRequested) { - this.state?.tokenSource?.cancel() + // Move to the next state + this._state = resp.nextState } - // Move to the next state - this._state = resp.nextState + return resp.interaction + } catch (e) { + if (e instanceof CommonAmazonQContentLengthError) { + throw new ContentLengthError() + } + throw e } - - return resp.interaction } public async updateFilesPaths( diff --git a/packages/core/src/amazonqFeatureDev/session/session.ts b/packages/core/src/amazonqFeatureDev/session/session.ts index 3ce3000757e..447d078d3cb 100644 --- a/packages/core/src/amazonqFeatureDev/session/session.ts +++ b/packages/core/src/amazonqFeatureDev/session/session.ts @@ -14,7 +14,7 @@ import { type SessionStateConfig, UpdateFilesPathsParams, } from '../../amazonq/commons/types' -import { ConversationIdNotFoundError } from '../errors' +import { ContentLengthError, ConversationIdNotFoundError } from '../errors' import { featureDevChat, referenceLogText, featureDevScheme } from '../constants' import fs from '../../shared/fs/fs' import { FeatureDevClient } from '../client/featureDev' @@ -33,6 +33,7 @@ import { UpdateAnswerMessage } from '../../amazonq/commons/connector/connectorMe import { FollowUpTypes } from '../../amazonq/commons/types' import { SessionConfig } from '../../amazonq/commons/session/sessionConfigFactory' import { Messenger } from '../../amazonq/commons/connector/baseMessenger' +import { CommonAmazonQContentLengthError } from '../../amazonq/errors' export class Session { private _state?: SessionState | Omit private task: string = '' @@ -137,25 +138,32 @@ export class Session { } private async nextInteraction(msg: string) { - const resp = await this.state.interact({ - task: this.task, - msg, - fs: this.config.fs, - messenger: this.messenger, - telemetry: this.telemetry, - tokenSource: this.state.tokenSource, - uploadHistory: this.state.uploadHistory, - }) + try { + const resp = await this.state.interact({ + task: this.task, + msg, + fs: this.config.fs, + messenger: this.messenger, + telemetry: this.telemetry, + tokenSource: this.state.tokenSource, + uploadHistory: this.state.uploadHistory, + }) - if (resp.nextState) { - if (!this.state?.tokenSource?.token.isCancellationRequested) { - this.state?.tokenSource?.cancel() + if (resp.nextState) { + if (!this.state?.tokenSource?.token.isCancellationRequested) { + this.state?.tokenSource?.cancel() + } + // Move to the next state + this._state = resp.nextState } - // Move to the next state - this._state = resp.nextState - } - return resp.interaction + return resp.interaction + } catch (e) { + if (e instanceof CommonAmazonQContentLengthError) { + throw new ContentLengthError() + } + throw e + } } public async updateFilesPaths(params: UpdateFilesPathsParams) { From f556ec8f4a5c20ac0aab97570e3ee4e5f1f313ed Mon Sep 17 00:00:00 2001 From: Kevin Ding Date: Tue, 25 Feb 2025 11:35:24 -0500 Subject: [PATCH 2/2] chore: update according to the comments --- .../test/unit/amazonqFeatureDev/util/files.test.ts | 3 +-- packages/core/src/amazonq/errors.ts | 9 +++++++-- packages/core/src/amazonq/index.ts | 1 + packages/core/src/amazonq/util/files.ts | 6 +++--- packages/core/src/amazonqDoc/session/session.ts | 3 ++- packages/core/src/amazonqFeatureDev/session/session.ts | 3 ++- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/amazonq/test/unit/amazonqFeatureDev/util/files.test.ts b/packages/amazonq/test/unit/amazonqFeatureDev/util/files.test.ts index e05cdee976c..badc34f6dd7 100644 --- a/packages/amazonq/test/unit/amazonqFeatureDev/util/files.test.ts +++ b/packages/amazonq/test/unit/amazonqFeatureDev/util/files.test.ts @@ -8,7 +8,6 @@ import { prepareRepoData, PrepareRepoDataOptions, TelemetryHelper, - ContentLengthError, maxRepoSizeBytes, } from 'aws-core-vscode/amazonqFeatureDev' import { assertTelemetry, getWorkspaceFolder, TestFolder } from 'aws-core-vscode/test' @@ -16,7 +15,7 @@ import { fs, AmazonqCreateUpload, ZipStream } from 'aws-core-vscode/shared' import { MetricName, Span } from 'aws-core-vscode/telemetry' import sinon from 'sinon' import { CodeWhispererSettings } from 'aws-core-vscode/codewhisperer' -import { CurrentWsFolders } from 'aws-core-vscode/amazonq' +import { ContentLengthError, CurrentWsFolders } from 'aws-core-vscode/amazonq' import path from 'path' const testDevfilePrepareRepo = async (devfileEnabled: boolean) => { diff --git a/packages/core/src/amazonq/errors.ts b/packages/core/src/amazonq/errors.ts index cf45cb61265..799206d7ab9 100644 --- a/packages/core/src/amazonq/errors.ts +++ b/packages/core/src/amazonq/errors.ts @@ -4,10 +4,15 @@ * */ +/** + * Shared error type for content length validation. + * When thrown from common components, individual agents can catch and transform this error + * to provide their own customized error messages. + */ import { ToolkitError } from '../shared/errors' -export class CommonAmazonQContentLengthError extends ToolkitError { +export class ContentLengthError extends ToolkitError { constructor(message: string) { - super(message, { code: 'CommonAmazonQContentLengthError' }) + super(message, { code: 'ContentLengthError' }) } } diff --git a/packages/core/src/amazonq/index.ts b/packages/core/src/amazonq/index.ts index b42a0c20a39..2eee9e7d4b2 100644 --- a/packages/core/src/amazonq/index.ts +++ b/packages/core/src/amazonq/index.ts @@ -43,6 +43,7 @@ export { ExtensionMessage } from '../amazonq/webview/ui/commands' export { CodeReference } from '../codewhispererChat/view/connector/connector' export { extractAuthFollowUp } from './util/authUtils' export { Messenger } from './commons/connector/baseMessenger' +export { ContentLengthError } from './errors' import { FeatureContext } from '../shared/featureConfig' /** diff --git a/packages/core/src/amazonq/util/files.ts b/packages/core/src/amazonq/util/files.ts index eef133c514f..b7c25c7f887 100644 --- a/packages/core/src/amazonq/util/files.ts +++ b/packages/core/src/amazonq/util/files.ts @@ -28,7 +28,7 @@ import { ZipStream } from '../../shared/utilities/zipStream' import { isPresent } from '../../shared/utilities/collectionUtils' import { AuthUtil } from '../../codewhisperer/util/authUtil' import { TelemetryHelper } from '../util/telemetryHelper' -import { CommonAmazonQContentLengthError } from '../errors' +import { ContentLengthError } from '../errors' export const SvgFileExtension = '.svg' @@ -185,9 +185,9 @@ export async function prepareRepoData( zipFileChecksum: zipResult.hash, } } catch (error) { - getLogger().debug(`featureDev: Failed to prepare repo: ${error}`) + getLogger().debug(`Failed to prepare repo: ${error}`) if (error instanceof ToolkitError && error.code === 'ContentLengthError') { - throw new CommonAmazonQContentLengthError(error.message) + throw new ContentLengthError(error.message) } throw new PrepareRepoFailedError() } diff --git a/packages/core/src/amazonqDoc/session/session.ts b/packages/core/src/amazonqDoc/session/session.ts index 73f725118ea..301a9d0e0fa 100644 --- a/packages/core/src/amazonqDoc/session/session.ts +++ b/packages/core/src/amazonqDoc/session/session.ts @@ -31,7 +31,7 @@ import globals from '../../shared/extensionGlobals' import { extensionVersion } from '../../shared/vscode/env' import { getLogger } from '../../shared/logger/logger' import { ContentLengthError } from '../errors' -import { CommonAmazonQContentLengthError } from '../../amazonq/errors' +import { ContentLengthError as CommonAmazonQContentLengthError } from '../../amazonq/errors' export class Session { private _state?: SessionState | Omit @@ -153,6 +153,7 @@ export class Session { return resp.interaction } catch (e) { if (e instanceof CommonAmazonQContentLengthError) { + getLogger().debug(`Content length validation failed: ${e.message}`) throw new ContentLengthError() } throw e diff --git a/packages/core/src/amazonqFeatureDev/session/session.ts b/packages/core/src/amazonqFeatureDev/session/session.ts index 447d078d3cb..6d692c297a4 100644 --- a/packages/core/src/amazonqFeatureDev/session/session.ts +++ b/packages/core/src/amazonqFeatureDev/session/session.ts @@ -33,7 +33,7 @@ import { UpdateAnswerMessage } from '../../amazonq/commons/connector/connectorMe import { FollowUpTypes } from '../../amazonq/commons/types' import { SessionConfig } from '../../amazonq/commons/session/sessionConfigFactory' import { Messenger } from '../../amazonq/commons/connector/baseMessenger' -import { CommonAmazonQContentLengthError } from '../../amazonq/errors' +import { ContentLengthError as CommonAmazonQContentLengthError } from '../../amazonq/errors' export class Session { private _state?: SessionState | Omit private task: string = '' @@ -160,6 +160,7 @@ export class Session { return resp.interaction } catch (e) { if (e instanceof CommonAmazonQContentLengthError) { + getLogger().debug(`Content length validation failed: ${e.message}`) throw new ContentLengthError() } throw e