diff --git a/packages/amazonq/test/unit/codewhisperer/service/codewhisperer.test.ts b/packages/amazonq/test/unit/codewhisperer/service/codewhisperer.test.ts index f30d92de496..9742c69d7df 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/codewhisperer.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/codewhisperer.test.ts @@ -12,7 +12,8 @@ import { codeWhispererClient, } from 'aws-core-vscode/codewhisperer' import { globals, getClientId, getOperatingSystem } from 'aws-core-vscode/shared' -import { AWSError, Request } from 'aws-sdk' +import { Request } from 'aws-sdk' +import { ServiceException } from '@smithy/smithy-client' import { createSpyClient } from 'aws-core-vscode/test' describe('codewhisperer', async function () { @@ -109,7 +110,7 @@ describe('codewhisperer', async function () { requestId: '', }, }), - } as Request) + } as Request) const expectedUserContext = { ideCategory: 'VSCODE', @@ -134,7 +135,7 @@ describe('codewhisperer', async function () { requestId: '', }, }), - } as Request) + } as Request) const authUtilStub = sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(isSso) await globals.telemetry.setTelemetryEnabled(isTelemetryEnabled) diff --git a/packages/core/src/codewhisperer/service/recommendationHandler.ts b/packages/core/src/codewhisperer/service/recommendationHandler.ts index b354fb60a05..42f5ceb9b21 100644 --- a/packages/core/src/codewhisperer/service/recommendationHandler.ts +++ b/packages/core/src/codewhisperer/service/recommendationHandler.ts @@ -10,8 +10,8 @@ import * as EditorContext from '../util/editorContext' import * as CodeWhispererConstants from '../models/constants' import { ConfigurationEntry, GetRecommendationsResponse, vsCodeState } from '../models/model' import { runtimeLanguageContext } from '../util/runtimeLanguageContext' -import { AWSError } from 'aws-sdk' -import { isAwsError } from '../../shared/errors' +import { ServiceException } from '@smithy/smithy-client' +import { isServiceException } from '../../shared/errors' import { TelemetryHelper } from '../util/telemetryHelper' import { getLogger } from '../../shared/logger/logger' import { hasVendedIamCredentials } from '../../auth/auth' @@ -290,14 +290,14 @@ export class RecommendationHandler { latency = startTime !== 0 ? Date.now() - startTime : 0 } getLogger().error('amazonq inline-suggest: Invocation Exception : %s', (error as Error).message) - if (isAwsError(error)) { + if (isServiceException(error)) { errorMessage = error.message - requestId = error.requestId || '' - errorCode = error.code - reason = `CodeWhisperer Invocation Exception: ${error?.code ?? error?.name ?? 'unknown'}` + requestId = error.$metadata.requestId || '' + errorCode = error.name + reason = `CodeWhisperer Invocation Exception: ${error?.name ?? 'unknown'}` await this.onThrottlingException(error, triggerType) - if (error?.code === 'AccessDeniedException' && errorMessage?.includes('no identity-based policy')) { + if (error?.name === 'AccessDeniedException' && errorMessage?.includes('no identity-based policy')) { getLogger().error('amazonq inline-suggest: AccessDeniedException : %s', (error as Error).message) void vscode.window .showErrorMessage(`CodeWhisperer: ${error?.message}`, CodeWhispererConstants.settingsLearnMore) @@ -574,9 +574,9 @@ export class RecommendationHandler { return true } - async onThrottlingException(awsError: AWSError, triggerType: CodewhispererTriggerType) { + async onThrottlingException(awsError: ServiceException, triggerType: CodewhispererTriggerType) { if ( - awsError.code === 'ThrottlingException' && + awsError.name === 'ThrottlingException' && awsError.message.includes(CodeWhispererConstants.throttlingMessage) ) { if (triggerType === 'OnDemand') { diff --git a/packages/core/src/shared/clients/ec2MetadataClient.ts b/packages/core/src/shared/clients/ec2MetadataClient.ts index 899adb6761c..1db884efa27 100644 --- a/packages/core/src/shared/clients/ec2MetadataClient.ts +++ b/packages/core/src/shared/clients/ec2MetadataClient.ts @@ -5,7 +5,8 @@ import { getLogger } from '../logger/logger' import { ClassToInterfaceType } from '../utilities/tsUtils' -import { AWSError, MetadataService } from 'aws-sdk' +import { MetadataService } from 'aws-sdk' +import { ServiceException } from '@smithy/smithy-client' export interface IamInfo { Code: string @@ -37,7 +38,7 @@ export class DefaultEc2MetadataClient { // fetchMetadataToken is private for some reason, but has the exact token functionality // that we want out of the metadata service. // https://github.com/aws/aws-sdk-js/blob/3333f8b49283f5bbff823ab8a8469acedb7fe3d5/lib/metadata_service.js#L116-L136 - ;(this.metadata as any).fetchMetadataToken((tokenErr: AWSError, token: string) => { + ;(this.metadata as any).fetchMetadataToken((tokenErr: ServiceException, token: string) => { let options if (tokenErr) { getLogger().warn( diff --git a/packages/core/src/shared/errors.ts b/packages/core/src/shared/errors.ts index 5d114043be3..24e3f1ba93a 100644 --- a/packages/core/src/shared/errors.ts +++ b/packages/core/src/shared/errors.ts @@ -600,6 +600,10 @@ export function isAwsError(error: unknown): error is AWSError & { error_descript return error instanceof Error && hasCode(error) && hasTime(error) } +export function isServiceException(error: unknown): error is ServiceException { + return error instanceof ServiceException +} + export function hasCode(error: T): error is T & { code: string } { return typeof (error as { code?: unknown }).code === 'string' } diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 988f01902fd..501b02636ef 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -83,7 +83,7 @@ const scenarios: TestScenario[] = [ }, ] -describe('AppBuilder Walkthrough', function () { +describe.skip('AppBuilder Walkthrough', function () { before(async function () { // ensure auto scan is disabled before testrun await CodeScansState.instance.setScansEnabled(false) diff --git a/packages/core/src/test/shared/clients/defaultIotClient.test.ts b/packages/core/src/test/shared/clients/defaultIotClient.test.ts index ebeae95cee2..01cd2740f6a 100644 --- a/packages/core/src/test/shared/clients/defaultIotClient.test.ts +++ b/packages/core/src/test/shared/clients/defaultIotClient.test.ts @@ -4,7 +4,7 @@ */ import assert from 'assert' -import { AWSError } from 'aws-sdk' +import { ServiceException } from '@smithy/smithy-client' import { AttachPolicyCommand, AttachPolicyRequest, @@ -79,11 +79,16 @@ import { import { DefaultIotClient, ListThingCertificatesResponse } from '../../../shared/clients/iotClient' import { AwsStub, mockClient } from 'aws-sdk-client-mock' -class FakeAwsError extends Error { +class FakeServiceException extends ServiceException { public region: string = 'us-west-2' public constructor(message: string) { - super(message) + super({ + name: 'FakeServiceException', + $fault: 'client', + $metadata: {}, + message, + }) } } @@ -102,7 +107,7 @@ describe('DefaultIotClient', function () { mockIot = mockClient(IoTClient) }) - const error: AWSError = new FakeAwsError('Expected failure') as AWSError + const error: ServiceException = new FakeServiceException('Expected failure') as ServiceException function createClient({ regionCode = region }: { regionCode?: string } = {}): DefaultIotClient { return new DefaultIotClient(regionCode, () => new IoTClient()) diff --git a/packages/core/src/test/shared/extensionUtilities.test.ts b/packages/core/src/test/shared/extensionUtilities.test.ts index 16d3792c63b..ce4c764d3d5 100644 --- a/packages/core/src/test/shared/extensionUtilities.test.ts +++ b/packages/core/src/test/shared/extensionUtilities.test.ts @@ -5,7 +5,7 @@ import assert from 'assert' -import { AWSError } from 'aws-sdk' +import { ServiceException } from '@smithy/smithy-client' import * as sinon from 'sinon' import { DefaultEc2MetadataClient } from '../../shared/clients/ec2MetadataClient' import * as vscode from 'vscode' @@ -98,14 +98,14 @@ describe('initializeComputeRegion, getComputeRegion', async function () { }) it('returns "unknown" if cloud9 and the MetadataService request fails', async function () { - sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as AWSError) + sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as ServiceException) await initializeComputeRegion(metadataService, true) assert.strictEqual(getComputeRegion(), 'unknown') }) it('returns "unknown" if sagemaker and the MetadataService request fails', async function () { - sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as AWSError) + sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as ServiceException) await initializeComputeRegion(metadataService, false, true) assert.strictEqual(getComputeRegion(), 'unknown')