Skip to content

Commit 1257328

Browse files
committed
gopls/internal/lsp/cache: don't panic when import fails during analysis
We have received a number of empty crash reports for gopls since cutting the v0.12.3 release. We don't want to auto-populate crash reports with log.Fatal messages (as unlike panicking stacks they may contain the name of user packages), so in almost all cases we lose information as to why gopls crashed (users are unlikely to pre-populate this information). In general, I don't think failing analysis should crash the process, so switch this failure mode to a bug report. Fixes golang/go#60963 Change-Id: I670ee4b1adbe9f37d763c5684b14d4bcb78dcb63 Reviewed-on: https://go-review.googlesource.com/c/tools/+/505575 gopls-CI: kokoro <[email protected]> Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> (cherry picked from commit fa10359) Reviewed-on: https://go-review.googlesource.com/c/tools/+/505576
1 parent 72cd703 commit 1257328

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

gopls/internal/lsp/cache/analysis.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,18 @@ type analysisNode struct {
408408
exportDeps map[PackagePath]*analysisNode // subset of allDeps ref'd by export data (+self)
409409
count int32 // number of unfinished successors
410410
summary *analyzeSummary // serializable result of analyzing this package
411-
typesOnce sync.Once // guards lazy population of types field
412-
types *types.Package // type information lazily imported from summary
411+
412+
typesOnce sync.Once // guards lazy population of types and typesErr fields
413+
types *types.Package // type information lazily imported from summary
414+
typesErr error // an error producing type information
413415
}
414416

415417
func (an *analysisNode) String() string { return string(an.m.ID) }
416418

417419
// _import imports this node's types.Package from export data, if not already done.
418420
// Precondition: analysis was a success.
419421
// Postcondition: an.types and an.exportDeps are populated.
420-
func (an *analysisNode) _import() *types.Package {
422+
func (an *analysisNode) _import() (*types.Package, error) {
421423
an.typesOnce.Do(func() {
422424
if an.m.PkgPath == "unsafe" {
423425
an.types = types.Unsafe
@@ -439,26 +441,33 @@ func (an *analysisNode) _import() *types.Package {
439441
}
440442
an.exportDeps[path] = dep // record, for later fact decoding
441443
if dep == an {
442-
items[i].Pkg = an.types
444+
if an.typesErr != nil {
445+
return an.typesErr
446+
} else {
447+
items[i].Pkg = an.types
448+
}
443449
} else {
444450
i := i
445451
g.Go(func() error {
446-
items[i].Pkg = dep._import()
447-
return nil
452+
depPkg, err := dep._import()
453+
if err == nil {
454+
items[i].Pkg = depPkg
455+
}
456+
return err
448457
})
449458
}
450459
}
451460
return g.Wait()
452461
}
453462
pkg, err := gcimporter.IImportShallow(an.fset, getPackages, an.summary.Export, string(an.m.PkgPath))
454463
if err != nil {
455-
log.Fatalf("%s: invalid export data: %v", an.m, err)
456-
}
457-
if pkg != an.types {
464+
an.typesErr = bug.Errorf("%s: invalid export data: %v", an.m, err)
465+
an.types = nil
466+
} else if pkg != an.types {
458467
log.Fatalf("%s: inconsistent packages", an.m)
459468
}
460469
})
461-
return an.types
470+
return an.types, an.typesErr
462471
}
463472

464473
// analyzeSummary is a gob-serializable summary of successfully
@@ -703,7 +712,10 @@ func (an *analysisNode) run(ctx context.Context) (*analyzeSummary, error) {
703712
// Does the fact relate to a package referenced by export data?
704713
if dep, ok := allExportDeps[PackagePath(path)]; ok {
705714
dep.typesOnce.Do(func() { log.Fatal("dep.types not populated") })
706-
return dep.types
715+
if dep.typesErr == nil {
716+
return dep.types
717+
}
718+
return nil
707719
}
708720

709721
// If the fact relates to a dependency not referenced
@@ -867,7 +879,7 @@ func (an *analysisNode) typeCheck(parsed []*source.ParsedGoFile) *analysisPackag
867879
return nil, fmt.Errorf("invalid use of internal package %s", importPath)
868880
}
869881

870-
return dep._import(), nil
882+
return dep._import()
871883
}),
872884
}
873885

0 commit comments

Comments
 (0)