Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down Expand Up @@ -109,7 +110,7 @@ describe('codewhisperer', async function () {
requestId: '',
},
}),
} as Request<SendTelemetryEventResponse, AWSError>)
} as Request<SendTelemetryEventResponse, ServiceException>)

const expectedUserContext = {
ideCategory: 'VSCODE',
Expand All @@ -134,7 +135,7 @@ describe('codewhisperer', async function () {
requestId: '',
},
}),
} as Request<SendTelemetryEventResponse, AWSError>)
} as Request<SendTelemetryEventResponse, ServiceException>)

const authUtilStub = sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(isSso)
await globals.telemetry.setTelemetryEnabled(isTelemetryEnabled)
Expand Down
18 changes: 9 additions & 9 deletions packages/core/src/codewhisperer/service/recommendationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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') {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/shared/clients/ec2MetadataClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/shared/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(error: T): error is T & { code: string } {
return typeof (error as { code?: unknown }).code === 'string'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 9 additions & 4 deletions packages/core/src/test/shared/clients/defaultIotClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import assert from 'assert'
import { AWSError } from 'aws-sdk'
import { ServiceException } from '@smithy/smithy-client'
import {
AttachPolicyCommand,
AttachPolicyRequest,
Expand Down Expand Up @@ -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,
})
}
}

Expand All @@ -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())
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/test/shared/extensionUtilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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')
Expand Down