@@ -6,6 +6,7 @@ package cache
6
6
7
7
import (
8
8
"context"
9
+ "errors"
9
10
"fmt"
10
11
"path/filepath"
11
12
"regexp"
@@ -297,36 +298,68 @@ func (s *snapshot) ModWhy(ctx context.Context, fh source.FileHandle) (map[string
297
298
298
299
// extractGoCommandError tries to parse errors that come from the go command
299
300
// and shape them into go.mod diagnostics.
300
- func (s * snapshot ) extractGoCommandErrors (ctx context.Context , goCmdError string ) ([]* source.Diagnostic , error ) {
301
- diagLocations := map [* source.ParsedModule ]span.Span {}
302
- backupDiagLocations := map [* source.ParsedModule ]span.Span {}
303
-
304
- // The go command emits parse errors for completely invalid go.mod files.
305
- // Those are reported by our own diagnostics and can be ignored here.
306
- // As of writing, we are not aware of any other errors that include
307
- // file/position information, so don't even try to find it.
308
- if strings .Contains (goCmdError , "errors parsing go.mod" ) {
309
- return nil , nil
301
+ // TODO: rename this to 'load errors'
302
+ func (s * snapshot ) extractGoCommandErrors (ctx context.Context , goCmdError error ) []* source.Diagnostic {
303
+ if goCmdError == nil {
304
+ return nil
305
+ }
306
+
307
+ type locatedErr struct {
308
+ spn span.Span
309
+ msg string
310
310
}
311
+ diagLocations := map [* source.ParsedModule ]locatedErr {}
312
+ backupDiagLocations := map [* source.ParsedModule ]locatedErr {}
313
+
314
+ // If moduleErrs is non-nil, go command errors are scoped to specific
315
+ // modules.
316
+ var moduleErrs * moduleErrorMap
317
+ _ = errors .As (goCmdError , & moduleErrs )
311
318
312
319
// Match the error against all the mod files in the workspace.
313
320
for _ , uri := range s .ModFiles () {
314
321
fh , err := s .GetFile (ctx , uri )
315
322
if err != nil {
316
- return nil , err
323
+ event .Error (ctx , "getting modfile for Go command error" , err )
324
+ continue
317
325
}
318
326
pm , err := s .ParseMod (ctx , fh )
319
327
if err != nil {
320
- return nil , err
321
- }
322
- spn , found , err := s .matchErrorToModule (ctx , pm , goCmdError )
323
- if err != nil {
324
- return nil , err
328
+ // Parsing errors are reported elsewhere
329
+ return nil
325
330
}
326
- if found {
327
- diagLocations [pm ] = spn
331
+ var msgs []string // error messages to consider
332
+ if moduleErrs != nil {
333
+ if pm .File .Module != nil {
334
+ for _ , mes := range moduleErrs .errs [pm .File .Module .Mod .Path ] {
335
+ msgs = append (msgs , mes .Error ())
336
+ }
337
+ }
328
338
} else {
329
- backupDiagLocations [pm ] = spn
339
+ msgs = append (msgs , goCmdError .Error ())
340
+ }
341
+ for _ , msg := range msgs {
342
+ if strings .Contains (goCmdError .Error (), "errors parsing go.mod" ) {
343
+ // The go command emits parse errors for completely invalid go.mod files.
344
+ // Those are reported by our own diagnostics and can be ignored here.
345
+ // As of writing, we are not aware of any other errors that include
346
+ // file/position information, so don't even try to find it.
347
+ continue
348
+ }
349
+ spn , found , err := s .matchErrorToModule (ctx , pm , msg )
350
+ if err != nil {
351
+ event .Error (ctx , "matching error to module" , err )
352
+ continue
353
+ }
354
+ le := locatedErr {
355
+ spn : spn ,
356
+ msg : msg ,
357
+ }
358
+ if found {
359
+ diagLocations [pm ] = le
360
+ } else {
361
+ backupDiagLocations [pm ] = le
362
+ }
330
363
}
331
364
}
332
365
@@ -336,14 +369,15 @@ func (s *snapshot) extractGoCommandErrors(ctx context.Context, goCmdError string
336
369
}
337
370
338
371
var srcErrs []* source.Diagnostic
339
- for pm , spn := range diagLocations {
340
- diag , err := s .goCommandDiagnostic (pm , spn , goCmdError )
372
+ for pm , le := range diagLocations {
373
+ diag , err := s .goCommandDiagnostic (pm , le . spn , le . msg )
341
374
if err != nil {
342
- return nil , err
375
+ event .Error (ctx , "building go command diagnostic" , err )
376
+ continue
343
377
}
344
378
srcErrs = append (srcErrs , diag )
345
379
}
346
- return srcErrs , nil
380
+ return srcErrs
347
381
}
348
382
349
383
var moduleVersionInErrorRe = regexp .MustCompile (`[:\s]([+-._~0-9A-Za-z]+)@([+-._~0-9A-Za-z]+)[:\s]` )
0 commit comments