Skip to content

Commit b101d34

Browse files
committed
refactor(AWSError): migrate AWSError to ServiceException part 1
1 parent 185406d commit b101d34

File tree

7 files changed

+41
-30
lines changed

7 files changed

+41
-30
lines changed

packages/amazonq/test/unit/codewhisperer/service/codewhisperer.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
codeWhispererClient,
1313
} from 'aws-core-vscode/codewhisperer'
1414
import { globals, getClientId, getOperatingSystem } from 'aws-core-vscode/shared'
15-
import { AWSError, Request } from 'aws-sdk'
15+
import { Request } from 'aws-sdk'
16+
import { ServiceException } from '@smithy/smithy-client'
1617
import { createSpyClient } from 'aws-core-vscode/test'
1718

1819
describe('codewhisperer', async function () {
@@ -109,7 +110,7 @@ describe('codewhisperer', async function () {
109110
requestId: '',
110111
},
111112
}),
112-
} as Request<SendTelemetryEventResponse, AWSError>)
113+
} as Request<SendTelemetryEventResponse, ServiceException>)
113114

114115
const expectedUserContext = {
115116
ideCategory: 'VSCODE',
@@ -134,7 +135,7 @@ describe('codewhisperer', async function () {
134135
requestId: '',
135136
},
136137
}),
137-
} as Request<SendTelemetryEventResponse, AWSError>)
138+
} as Request<SendTelemetryEventResponse, ServiceException>)
138139

139140
const authUtilStub = sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(isSso)
140141
await globals.telemetry.setTelemetryEnabled(isTelemetryEnabled)

packages/core/src/codewhisperer/service/recommendationHandler.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import * as EditorContext from '../util/editorContext'
1010
import * as CodeWhispererConstants from '../models/constants'
1111
import { ConfigurationEntry, GetRecommendationsResponse, vsCodeState } from '../models/model'
1212
import { runtimeLanguageContext } from '../util/runtimeLanguageContext'
13-
import { AWSError } from 'aws-sdk'
14-
import { isAwsError } from '../../shared/errors'
13+
import { ServiceException } from '@smithy/smithy-client'
14+
import { isServiceException } from '../../shared/errors'
1515
import { TelemetryHelper } from '../util/telemetryHelper'
1616
import { getLogger } from '../../shared/logger/logger'
1717
import { hasVendedIamCredentials } from '../../auth/auth'
@@ -290,14 +290,14 @@ export class RecommendationHandler {
290290
latency = startTime !== 0 ? Date.now() - startTime : 0
291291
}
292292
getLogger().error('amazonq inline-suggest: Invocation Exception : %s', (error as Error).message)
293-
if (isAwsError(error)) {
293+
if (isServiceException(error)) {
294294
errorMessage = error.message
295-
requestId = error.requestId || ''
296-
errorCode = error.code
297-
reason = `CodeWhisperer Invocation Exception: ${error?.code ?? error?.name ?? 'unknown'}`
295+
requestId = error.$metadata.requestId || ''
296+
errorCode = error.name
297+
reason = `CodeWhisperer Invocation Exception: ${error?.name ?? 'unknown'}`
298298
await this.onThrottlingException(error, triggerType)
299299

300-
if (error?.code === 'AccessDeniedException' && errorMessage?.includes('no identity-based policy')) {
300+
if (error?.name === 'AccessDeniedException' && errorMessage?.includes('no identity-based policy')) {
301301
getLogger().error('amazonq inline-suggest: AccessDeniedException : %s', (error as Error).message)
302302
void vscode.window
303303
.showErrorMessage(`CodeWhisperer: ${error?.message}`, CodeWhispererConstants.settingsLearnMore)
@@ -574,9 +574,9 @@ export class RecommendationHandler {
574574
return true
575575
}
576576

577-
async onThrottlingException(awsError: AWSError, triggerType: CodewhispererTriggerType) {
577+
async onThrottlingException(awsError: ServiceException, triggerType: CodewhispererTriggerType) {
578578
if (
579-
awsError.code === 'ThrottlingException' &&
579+
awsError.name === 'ThrottlingException' &&
580580
awsError.message.includes(CodeWhispererConstants.throttlingMessage)
581581
) {
582582
if (triggerType === 'OnDemand') {

packages/core/src/shared/clients/ec2MetadataClient.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
import { getLogger } from '../logger/logger'
77
import { ClassToInterfaceType } from '../utilities/tsUtils'
8-
import { AWSError, MetadataService } from 'aws-sdk'
8+
import { MetadataService } from 'aws-sdk'
9+
import { ServiceException } from '@smithy/smithy-client'
910

1011
export interface IamInfo {
1112
Code: string
@@ -37,7 +38,7 @@ export class DefaultEc2MetadataClient {
3738
// fetchMetadataToken is private for some reason, but has the exact token functionality
3839
// that we want out of the metadata service.
3940
// https://github.com/aws/aws-sdk-js/blob/3333f8b49283f5bbff823ab8a8469acedb7fe3d5/lib/metadata_service.js#L116-L136
40-
;(this.metadata as any).fetchMetadataToken((tokenErr: AWSError, token: string) => {
41+
;(this.metadata as any).fetchMetadataToken((tokenErr: ServiceException, token: string) => {
4142
let options
4243
if (tokenErr) {
4344
getLogger().warn(

packages/core/src/shared/errors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ export function isAwsError(error: unknown): error is AWSError & { error_descript
600600
return error instanceof Error && hasCode(error) && hasTime(error)
601601
}
602602

603+
export function isServiceException(error: unknown): error is ServiceException {
604+
return error instanceof ServiceException
605+
}
606+
603607
export function hasCode<T>(error: T): error is T & { code: string } {
604608
return typeof (error as { code?: unknown }).code === 'string'
605609
}

packages/core/src/test/codewhisperer/startSecurityScan.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as diagnosticsProvider from '../../codewhisperer/service/diagnosticsPro
1414
import { getTestWorkspaceFolder } from '../../testInteg/integrationTestsUtilities'
1515
import { join } from 'path'
1616
import { assertTelemetry, closeAllEditors, getFetchStubWithResponse } from '../testUtil'
17-
import { AWSError } from 'aws-sdk'
17+
import { ServiceException } from '@smithy/smithy-client'
1818
import { getTestWindow } from '../shared/vscode/window'
1919
import { SeverityLevel } from '../shared/vscode/message'
2020
import { cancel } from '../../shared/localizedText'
@@ -334,11 +334,11 @@ describe('startSecurityScan', function () {
334334
getFetchStubWithResponse({ status: 200, statusText: 'testing stub' })
335335
const mockClient = createClient()
336336
mockClient.createCodeScan.throws({
337-
code: 'ThrottlingException',
338-
time: new Date(),
339-
name: 'error name',
337+
name: 'ThrottlingException',
340338
message: scansLimitReachedErrorMessage,
341-
} satisfies AWSError)
339+
$fault: 'client',
340+
$metadata: {},
341+
} satisfies ServiceException)
342342
sinon.stub(errors, 'isAwsError').returns(true)
343343
const testWindow = getTestWindow()
344344
await startSecurityScan.startSecurityScan(
@@ -365,11 +365,11 @@ describe('startSecurityScan', function () {
365365
await model.CodeScansState.instance.setScansEnabled(true)
366366
const mockClient = createClient()
367367
mockClient.createCodeScan.throws({
368-
code: 'ThrottlingException',
369-
time: new Date(),
370-
name: 'error name',
368+
name: 'ThrottlingException',
371369
message: 'Maximum file scans count reached for this month',
372-
} satisfies AWSError)
370+
$fault: 'client',
371+
$metadata: {},
372+
} satisfies ServiceException)
373373
sinon.stub(errors, 'isAwsError').returns(true)
374374
assert.equal(model.CodeScansState.instance.isMonthlyQuotaExceeded(), false)
375375
await startSecurityScan.startSecurityScan(

packages/core/src/test/shared/clients/defaultIotClient.test.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import assert from 'assert'
7-
import { AWSError } from 'aws-sdk'
7+
import { ServiceException } from '@smithy/smithy-client'
88
import {
99
AttachPolicyCommand,
1010
AttachPolicyRequest,
@@ -79,11 +79,16 @@ import {
7979
import { DefaultIotClient, ListThingCertificatesResponse } from '../../../shared/clients/iotClient'
8080
import { AwsStub, mockClient } from 'aws-sdk-client-mock'
8181

82-
class FakeAwsError extends Error {
82+
class FakeServiceException extends ServiceException {
8383
public region: string = 'us-west-2'
8484

8585
public constructor(message: string) {
86-
super(message)
86+
super({
87+
name: 'FakeServiceException',
88+
$fault: 'client',
89+
$metadata: {},
90+
message,
91+
})
8792
}
8893
}
8994

@@ -102,7 +107,7 @@ describe('DefaultIotClient', function () {
102107
mockIot = mockClient(IoTClient)
103108
})
104109

105-
const error: AWSError = new FakeAwsError('Expected failure') as AWSError
110+
const error: ServiceException = new FakeServiceException('Expected failure') as ServiceException
106111

107112
function createClient({ regionCode = region }: { regionCode?: string } = {}): DefaultIotClient {
108113
return new DefaultIotClient(regionCode, () => new IoTClient())

packages/core/src/test/shared/extensionUtilities.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import assert from 'assert'
77

8-
import { AWSError } from 'aws-sdk'
8+
import { ServiceException } from '@smithy/smithy-client'
99
import * as sinon from 'sinon'
1010
import { DefaultEc2MetadataClient } from '../../shared/clients/ec2MetadataClient'
1111
import * as vscode from 'vscode'
@@ -98,14 +98,14 @@ describe('initializeComputeRegion, getComputeRegion', async function () {
9898
})
9999

100100
it('returns "unknown" if cloud9 and the MetadataService request fails', async function () {
101-
sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as AWSError)
101+
sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as ServiceException)
102102

103103
await initializeComputeRegion(metadataService, true)
104104
assert.strictEqual(getComputeRegion(), 'unknown')
105105
})
106106

107107
it('returns "unknown" if sagemaker and the MetadataService request fails', async function () {
108-
sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as AWSError)
108+
sandbox.stub(metadataService, 'getInstanceIdentity').rejects({} as ServiceException)
109109

110110
await initializeComputeRegion(metadataService, false, true)
111111
assert.strictEqual(getComputeRegion(), 'unknown')

0 commit comments

Comments
 (0)