55
66import * as vscode from 'vscode'
77import * as path from 'path'
8- import { getLogger } from 'aws-core-vscode/shared'
98import { Problem } from './problemDetector'
109
1110export interface ErrorContext {
@@ -35,84 +34,6 @@ export interface FormattedErrorReport {
3534 * Formats diagnostic errors into contextual information for AI debugging assistance.
3635 */
3736export class ErrorContextFormatter {
38- private readonly logger = getLogger ( )
39- /**
40- * Converts a Problem to detailed ErrorContext
41- */
42- public async createErrorContext ( problem : Problem ) : Promise < ErrorContext > {
43- const surroundingCode = await this . extractSurroundingCode ( problem . uri , problem . diagnostic . range )
44-
45- const context : ErrorContext = {
46- source : problem . source ,
47- severity : problem . severity ,
48- location : {
49- file : path . relative ( vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' , problem . uri . fsPath ) ,
50- line : problem . diagnostic . range . start . line + 1 , // Convert from 0-indexed
51- column : problem . diagnostic . range . start . character + 1 , // Convert from 0-indexed
52- range : problem . diagnostic . range ,
53- } ,
54- message : problem . diagnostic . message ,
55- code : problem . diagnostic . code ?. toString ( ) ,
56- relatedInformation : problem . diagnostic . relatedInformation ,
57- surroundingCode,
58- }
59- return context
60- }
61-
62- /**
63- * Formats multiple error contexts into a comprehensive report
64- */
65- public formatErrorReport ( contexts : ErrorContext [ ] ) : FormattedErrorReport {
66- const summary = this . createSummary ( contexts )
67- const details = this . createDetails ( contexts )
68- const contextualCode = this . createContextualCode ( contexts )
69- const suggestions = this . createSuggestions ( contexts )
70-
71- return {
72- summary,
73- details,
74- contextualCode,
75- suggestions,
76- }
77- }
78-
79- /**
80- * Formats a single error context for display
81- */
82- public formatSingleError ( context : ErrorContext ) : string {
83- const parts = [
84- `**${ context . severity . toUpperCase ( ) } ** in ${ context . location . file } ` ,
85- `Line ${ context . location . line } , Column ${ context . location . column } ` ,
86- `Source: ${ context . source } ` ,
87- context . code ? `Code: ${ context . code } ` : undefined ,
88- '' ,
89- `**Message:** ${ context . message } ` ,
90- '' ,
91- ] . filter ( Boolean )
92-
93- if ( context . surroundingCode ) {
94- parts . push ( '**Code Context:**' )
95- parts . push ( '```typescript' )
96- parts . push ( context . surroundingCode )
97- parts . push ( '```' )
98- parts . push ( '' )
99- }
100-
101- if ( context . relatedInformation && context . relatedInformation . length > 0 ) {
102- parts . push ( '**Related Information:**' )
103- for ( const info of context . relatedInformation ) {
104- const relativeFile = path . relative (
105- vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' ,
106- info . location . uri . fsPath
107- )
108- parts . push ( `- ${ relativeFile } :${ info . location . range . start . line + 1 } - ${ info . message } ` )
109- }
110- parts . push ( '' )
111- }
112-
113- return parts . join ( '\n' )
114- }
115-
11637 /**
11738 * Creates a problems string with Markdown formatting for better readability
11839 */
@@ -138,105 +59,6 @@ export class ErrorContextFormatter {
13859 return result . trim ( )
13960 }
14061
141- /**
142- * Extracts code context around a diagnostic range
143- */
144- private async extractSurroundingCode ( uri : vscode . Uri , range : vscode . Range ) : Promise < string | undefined > {
145- try {
146- const document = await vscode . workspace . openTextDocument ( uri )
147- const startLine = Math . max ( 0 , range . start . line - 3 )
148- const endLine = Math . min ( document . lineCount - 1 , range . end . line + 3 )
149-
150- const lines : string [ ] = [ ]
151- for ( let i = startLine ; i <= endLine ; i ++ ) {
152- const lineText = document . lineAt ( i ) . text
153- const lineNumber = ( i + 1 ) . toString ( ) . padStart ( 3 , ' ' )
154- const marker = i >= range . start . line && i <= range . end . line ? '>' : ' '
155- lines . push ( `${ lineNumber } ${ marker } ${ lineText } ` )
156- }
157-
158- return lines . join ( '\n' )
159- } catch ( error ) {
160- this . logger . warn ( 'ErrorContextFormatter: Failed to extract surrounding code: %s' , error )
161- return undefined
162- }
163- }
164-
165- private createSummary ( contexts : ErrorContext [ ] ) : string {
166- const errorCount = contexts . filter ( ( c ) => c . severity === 'error' ) . length
167- const warningCount = contexts . filter ( ( c ) => c . severity === 'warning' ) . length
168-
169- const parts = [ ]
170- if ( errorCount > 0 ) {
171- parts . push ( `${ errorCount } error${ errorCount !== 1 ? 's' : '' } ` )
172- }
173- if ( warningCount > 0 ) {
174- parts . push ( `${ warningCount } warning${ warningCount !== 1 ? 's' : '' } ` )
175- }
176-
177- return `Found ${ parts . join ( ' and ' ) } in your code`
178- }
179-
180- private createDetails ( contexts : ErrorContext [ ] ) : string {
181- return contexts . map ( ( context ) => this . formatSingleError ( context ) ) . join ( '\n---\n\n' )
182- }
183-
184- private createContextualCode ( contexts : ErrorContext [ ] ) : string {
185- const codeBlocks = contexts
186- . filter ( ( context ) => context . surroundingCode )
187- . map ( ( context ) => `**${ context . location . file } :**\n\`\`\`typescript\n${ context . surroundingCode } \n\`\`\`` )
188-
189- return codeBlocks . join ( '\n\n' )
190- }
191-
192- private createSuggestions ( contexts : ErrorContext [ ] ) : string {
193- const suggestions = [ ]
194-
195- // Group by error type for better suggestions
196- const errorTypes = new Map < string , ErrorContext [ ] > ( )
197- for ( const context of contexts ) {
198- const key = context . source || 'unknown'
199- if ( ! errorTypes . has ( key ) ) {
200- errorTypes . set ( key , [ ] )
201- }
202- errorTypes . get ( key ) ! . push ( context )
203- }
204-
205- for ( const [ source , sourceContexts ] of errorTypes ) {
206- suggestions . push ( `**${ source } Issues (${ sourceContexts . length } ):**` )
207- suggestions . push ( this . generateSourceSpecificSuggestions ( source , sourceContexts ) )
208- }
209-
210- return suggestions . join ( '\n\n' )
211- }
212-
213- private generateSourceSpecificSuggestions ( source : string , contexts : ErrorContext [ ] ) : string {
214- // Basic suggestions based on common error patterns
215- const suggestions = [ ]
216-
217- if ( source . includes ( 'typescript' ) || source . includes ( 'ts' ) ) {
218- suggestions . push ( '- Check type definitions and imports' )
219- suggestions . push ( '- Verify function signatures and return types' )
220- }
221-
222- if ( source . includes ( 'eslint' ) ) {
223- suggestions . push ( '- Review code style and formatting' )
224- suggestions . push ( '- Check for unused variables and imports' )
225- }
226-
227- if ( contexts . some ( ( c ) => c . message . includes ( 'Cannot find module' ) ) ) {
228- suggestions . push ( '- Verify module installation: npm install or yarn install' )
229- suggestions . push ( '- Check import paths and module names' )
230- }
231-
232- if ( contexts . some ( ( c ) => c . message . includes ( 'is not assignable' ) ) ) {
233- suggestions . push ( '- Review type compatibility' )
234- suggestions . push ( '- Consider type assertions or interface updates' )
235- }
236-
237- return suggestions . length > 0 ? suggestions . join ( '\n' ) : '- Review the specific error messages above'
238- }
239-
24062 private groupProblemsByFile ( problems : Problem [ ] ) : Map < string , Problem [ ] > {
24163 const groups = new Map < string , Problem [ ] > ( )
24264
0 commit comments