Skip to content

Commit 1e45112

Browse files
authored
fix(amazonq): handle response errors from lsp (#7161)
## Problem Response errors returned by the LSP are returned to chat after prepending a custom error message. We can remove this custom error message and rely on flare for a single implementation of this error message. ## Solution - perform a sanity check on the response before casting it to the proper type. - log the last result from the language server to help debug. - include the requestId clearly in the logs. <img width="1061" alt="image" src="https://github.com/user-attachments/assets/fd71ed26-7266-47ee-9204-c1ec412ca452" /> --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent dd9ad62 commit 1e45112

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { ChatResult } from '@aws/language-server-runtimes/protocol'
6+
import { ResponseError } from '@aws/language-server-runtimes/protocol'
7+
/**
8+
* Perform a sanity check that the error we got from the LSP can be safely cast to the expected type.
9+
* @param error
10+
* @returns
11+
*/
12+
export function isValidResponseError(error: unknown): error is ResponseError<ChatResult> & { data: ChatResult } {
13+
return (
14+
typeof error === 'object' &&
15+
error !== null &&
16+
'code' in error &&
17+
typeof error.code === 'number' &&
18+
'message' in error &&
19+
typeof error.message === 'string' &&
20+
'data' in error &&
21+
error.data !== undefined
22+
)
23+
}

packages/amazonq/src/lsp/chat/messages.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import { AuthUtil } from 'aws-core-vscode/codewhisperer'
6161
import { amazonQDiffScheme, AmazonQPromptSettings, messages, openUrl } from 'aws-core-vscode/shared'
6262
import { DefaultAmazonQAppInitContext, messageDispatcher, EditorContentController } from 'aws-core-vscode/amazonq'
6363
import { telemetry, TelemetryBase } from 'aws-core-vscode/telemetry'
64+
import { isValidResponseError } from './error'
6465

6566
export function registerLanguageServerEventListener(languageClient: LanguageClient, provider: AmazonQChatViewProvider) {
6667
languageClient.info(
@@ -255,22 +256,16 @@ export function registerMessageListeners(
255256
chatDisposable
256257
)
257258
} catch (e) {
258-
languageClient.info(`Error occurred during chat request: ${e}`)
259-
// Use the last partial result if available, append error message
260-
let body = ''
261-
if (!cancellationToken.token.isCancellationRequested) {
262-
body = lastPartialResult?.body
263-
? `${lastPartialResult.body}\n\n ❌ Error: Request failed to complete`
264-
: '❌ An error occurred while processing your request'
265-
}
266-
267-
const errorResult: ChatResult = {
268-
...lastPartialResult,
269-
body,
259+
const errorMsg = `Error occurred during chat request: ${e}`
260+
languageClient.info(errorMsg)
261+
languageClient.info(
262+
`Last result from langauge server: ${JSON.stringify(lastPartialResult, undefined, 2)}`
263+
)
264+
if (!isValidResponseError(e)) {
265+
throw e
270266
}
271-
272267
await handleCompleteResult<ChatResult>(
273-
errorResult,
268+
e.data,
274269
encryptionKey,
275270
provider,
276271
chatParams.tabId,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { isValidResponseError } from '../../../../../src/lsp/chat/error'
7+
import { ResponseError } from '@aws/language-server-runtimes/protocol'
8+
import * as assert from 'assert'
9+
10+
describe('isValidResponseError', async function () {
11+
it('requires the data field', function () {
12+
assert.ok(isValidResponseError(new ResponseError(0, 'this one has data', {})))
13+
assert.ok(!isValidResponseError(new ResponseError(0, 'this one does not have data')))
14+
})
15+
})

0 commit comments

Comments
 (0)