Skip to content

Commit 04644c2

Browse files
committed
fix(amazonq): codefix does not do error handling
1 parent c153b02 commit 04644c2

File tree

7 files changed

+206
-195
lines changed

7 files changed

+206
-195
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "/review: Improved error handling for code fix operations"
4+
}

packages/core/resources/css/securityIssue.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,13 @@ pre.center {
524524

525525
pre.error {
526526
color: var(--vscode-diffEditorOverview-removedForeground);
527+
background-color: var(--vscode-diffEditor-removedTextBackground);
528+
white-space: initial;
529+
}
530+
531+
a.cursor {
532+
cursor: pointer;
533+
text-decoration: none;
527534
}
528535

529536
.dot-typing {

packages/core/src/codewhisperer/commands/basicCommands.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import { once } from '../../shared/utilities/functionUtils'
5050
import { focusAmazonQPanel } from '../../codewhispererChat/commands/registerCommands'
5151
import { removeDiagnostic } from '../service/diagnosticsProvider'
5252
import { SsoAccessTokenProvider } from '../../auth/sso/ssoAccessTokenProvider'
53-
import { ToolkitError, getTelemetryReason, getTelemetryReasonDesc } from '../../shared/errors'
53+
import { ToolkitError, getErrorMsg, getTelemetryReason, getTelemetryReasonDesc } from '../../shared/errors'
5454
import { isRemoteWorkspace } from '../../shared/vscode/env'
5555
import { isBuilderIdConnection } from '../../auth/connection'
5656
import globals from '../../shared/extensionGlobals'
@@ -67,6 +67,7 @@ import { startCodeFixGeneration } from './startCodeFixGeneration'
6767
import { DefaultAmazonQAppInitContext } from '../../amazonq/apps/initContext'
6868
import path from 'path'
6969
import { parsePatch } from 'diff'
70+
import type { AWSError } from 'aws-sdk'
7071

7172
const MessageTimeOut = 5_000
7273

@@ -677,7 +678,8 @@ export const generateFix = Commands.declare(
677678
})
678679
await updateSecurityIssueWebview({
679680
isGenerateFixLoading: true,
680-
isGenerateFixError: false,
681+
// eslint-disable-next-line unicorn/no-null
682+
generateFixError: null,
681683
context: context.extensionContext,
682684
filePath: targetFilePath,
683685
shouldRefreshView: false,
@@ -737,22 +739,23 @@ export const generateFix = Commands.declare(
737739
await updateSecurityIssueWebview({
738740
issue: targetIssue,
739741
isGenerateFixLoading: false,
740-
isGenerateFixError: true,
742+
generateFixError: getErrorMsg(err as AWSError, true),
741743
filePath: targetFilePath,
742744
context: context.extensionContext,
743-
shouldRefreshView: true,
745+
shouldRefreshView: false,
744746
})
745747
SecurityIssueProvider.instance.updateIssue(targetIssue, targetFilePath)
746748
SecurityIssueTreeViewProvider.instance.refresh()
747749
throw err
750+
} finally {
751+
telemetry.record({
752+
component: targetSource,
753+
detectorId: targetIssue.detectorId,
754+
findingId: targetIssue.findingId,
755+
ruleId: targetIssue.ruleId,
756+
variant: refresh ? 'refresh' : undefined,
757+
})
748758
}
749-
telemetry.record({
750-
component: targetSource,
751-
detectorId: targetIssue.detectorId,
752-
findingId: targetIssue.findingId,
753-
ruleId: targetIssue.ruleId,
754-
variant: refresh ? 'refresh' : undefined,
755-
})
756759
})
757760
}
758761
)

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ import * as CodeWhispererConstants from '../models/constants'
88
import { codeFixState } from '../models/model'
99
import { getLogger, sleep } from '../../shared'
1010
import { ArtifactMap, CreateUploadUrlRequest, DefaultCodeWhispererClient } from '../client/codewhisperer'
11-
import {
12-
CodeFixJobStoppedError,
13-
CodeFixJobTimedOutError,
14-
CreateCodeFixError,
15-
CreateUploadUrlError,
16-
} from '../models/errors'
11+
import { CodeFixJobStoppedError, CodeFixJobTimedOutError } from '../models/errors'
1712
import { uploadArtifactToS3 } from './securityScanHandler'
1813

1914
export async function getPresignedUrlAndUpload(
@@ -28,8 +23,8 @@ export async function getPresignedUrlAndUpload(
2823
}
2924
getLogger().verbose(`Prepare for uploading src context...`)
3025
const srcResp = await client.createUploadUrl(srcReq).catch((err) => {
31-
getLogger().error(`Failed getting presigned url for uploading src context. Request id: ${err.requestId}`)
32-
throw new CreateUploadUrlError(err)
26+
getLogger().error('Failed getting presigned url for uploading src context. %O', err)
27+
throw err
3328
})
3429
getLogger().verbose(`CreateUploadUrlRequest requestId: ${srcResp.$response.requestId}`)
3530
getLogger().verbose(`Complete Getting presigned Url for uploading src context.`)
@@ -60,8 +55,8 @@ export async function createCodeFixJob(
6055
}
6156

6257
const resp = await client.startCodeFixJob(req).catch((err) => {
63-
getLogger().error(`Failed creating code fix job. Request id: ${err.requestId}`)
64-
throw new CreateCodeFixError()
58+
getLogger().error('Failed creating code fix job. %O', err)
59+
throw err
6560
})
6661
getLogger().info(`AmazonQ generate fix Request id: ${resp.$response.requestId}`)
6762
return resp

packages/core/src/codewhisperer/views/securityIssue/securityIssueWebview.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ export class SecurityIssueWebview extends VueWebview {
2727
public readonly onChangeIssue = new vscode.EventEmitter<CodeScanIssue | undefined>()
2828
public readonly onChangeFilePath = new vscode.EventEmitter<string | undefined>()
2929
public readonly onChangeGenerateFixLoading = new vscode.EventEmitter<boolean>()
30-
public readonly onChangeGenerateFixError = new vscode.EventEmitter<boolean>()
30+
public readonly onChangeGenerateFixError = new vscode.EventEmitter<string | null | undefined>()
3131

3232
private issue: CodeScanIssue | undefined
3333
private filePath: string | undefined
3434
private isGenerateFixLoading: boolean = false
35-
private isGenerateFixError: boolean = false
35+
private generateFixError: string | null | undefined = undefined
3636

3737
public constructor() {
3838
super(SecurityIssueWebview.sourcePath)
@@ -99,13 +99,13 @@ export class SecurityIssueWebview extends VueWebview {
9999
this.onChangeGenerateFixLoading.fire(isGenerateFixLoading)
100100
}
101101

102-
public getIsGenerateFixError() {
103-
return this.isGenerateFixError
102+
public getGenerateFixError() {
103+
return this.generateFixError
104104
}
105105

106-
public setIsGenerateFixError(isGenerateFixError: boolean) {
107-
this.isGenerateFixError = isGenerateFixError
108-
this.onChangeGenerateFixError.fire(isGenerateFixError)
106+
public setGenerateFixError(generateFixError: string | null | undefined) {
107+
this.generateFixError = generateFixError
108+
this.onChangeGenerateFixError.fire(generateFixError)
109109
}
110110

111111
public generateFix() {
@@ -201,7 +201,7 @@ export async function showSecurityIssueWebview(ctx: vscode.ExtensionContext, iss
201201
activePanel.server.setIssue(issue)
202202
activePanel.server.setFilePath(filePath)
203203
activePanel.server.setIsGenerateFixLoading(false)
204-
activePanel.server.setIsGenerateFixError(false)
204+
activePanel.server.setGenerateFixError(undefined)
205205

206206
const webviewPanel = await activePanel.show({
207207
title: amazonqCodeIssueDetailsTabTitle,
@@ -247,15 +247,15 @@ type WebviewParams = {
247247
issue?: CodeScanIssue
248248
filePath?: string
249249
isGenerateFixLoading?: boolean
250-
isGenerateFixError?: boolean
250+
generateFixError?: string | null
251251
shouldRefreshView: boolean
252252
context: vscode.ExtensionContext
253253
}
254254
export async function updateSecurityIssueWebview({
255255
issue,
256256
filePath,
257257
isGenerateFixLoading,
258-
isGenerateFixError,
258+
generateFixError,
259259
shouldRefreshView,
260260
context,
261261
}: WebviewParams): Promise<void> {
@@ -271,8 +271,8 @@ export async function updateSecurityIssueWebview({
271271
if (isGenerateFixLoading !== undefined) {
272272
activePanel.server.setIsGenerateFixLoading(isGenerateFixLoading)
273273
}
274-
if (isGenerateFixError !== undefined) {
275-
activePanel.server.setIsGenerateFixError(isGenerateFixError)
274+
if (generateFixError !== undefined) {
275+
activePanel.server.setGenerateFixError(generateFixError)
276276
}
277277
if (shouldRefreshView && filePath && issue) {
278278
await showSecurityIssueWebview(context, issue, filePath)

packages/core/src/codewhisperer/views/securityIssue/vue/root.vue

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,14 @@
4848
</div>
4949

5050
<div
51-
v-if="isFixAvailable || isGenerateFixLoading || isGenerateFixError || isFixDescriptionAvailable"
51+
v-if="isFixAvailable || isGenerateFixLoading || generateFixError || isFixDescriptionAvailable"
5252
ref="codeFixSection"
5353
>
5454
<hr />
5555

5656
<h3>Suggested code fix preview</h3>
5757
<pre v-if="isGenerateFixLoading" class="center"><div class="dot-typing"></div></pre>
58-
<pre v-if="isGenerateFixError" class="center error">
59-
Something went wrong. <a @click="regenerateFix">Retry</a>
60-
</pre>
58+
<pre v-if="generateFixError" class="center error">{{ generateFixError }}</pre>
6159
<div class="code-block">
6260
<span v-if="isFixAvailable" v-html="suggestedFixHtml"></span>
6361
<div v-if="isFixAvailable" class="code-diff-actions" ref="codeFixAction">
@@ -195,7 +193,7 @@ export default defineComponent({
195193
endLine: 0,
196194
relativePath: '',
197195
isGenerateFixLoading: false,
198-
isGenerateFixError: false,
196+
generateFixError: undefined as string | null | undefined,
199197
languageId: 'plaintext',
200198
fixedCode: '',
201199
referenceText: '',
@@ -218,8 +216,8 @@ export default defineComponent({
218216
const relativePath = await client.getRelativePath()
219217
this.updateRelativePath(relativePath)
220218
const isGenerateFixLoading = await client.getIsGenerateFixLoading()
221-
const isGenerateFixError = await client.getIsGenerateFixError()
222-
this.updateGenerateFixState(isGenerateFixLoading, isGenerateFixError)
219+
const generateFixError = await client.getGenerateFixError()
220+
this.updateGenerateFixState(isGenerateFixLoading, generateFixError)
223221
const languageId = await client.getLanguageId()
224222
if (languageId) {
225223
this.updateLanguageId(languageId)
@@ -249,16 +247,16 @@ export default defineComponent({
249247
this.isGenerateFixLoading = isGenerateFixLoading
250248
this.scrollTo('codeFixSection')
251249
})
252-
client.onChangeGenerateFixError((isGenerateFixError) => {
253-
this.isGenerateFixError = isGenerateFixError
250+
client.onChangeGenerateFixError((generateFixError) => {
251+
this.generateFixError = generateFixError
254252
})
255253
},
256254
updateRelativePath(relativePath: string) {
257255
this.relativePath = relativePath
258256
},
259-
updateGenerateFixState(isGenerateFixLoading: boolean, isGenerateFixError: boolean) {
257+
updateGenerateFixState(isGenerateFixLoading: boolean, generateFixError: string | null | undefined) {
260258
this.isGenerateFixLoading = isGenerateFixLoading
261-
this.isGenerateFixError = isGenerateFixError
259+
this.generateFixError = generateFixError
262260
},
263261
updateLanguageId(languageId: string) {
264262
this.languageId = languageId

0 commit comments

Comments
 (0)