зеркало из https://github.com/golang/tools.git
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 <noreply+kokoro@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit fa103593d0
)
Reviewed-on: https://go-review.googlesource.com/c/tools/+/505576
This commit is contained in:
Родитель
72cd703b6d
Коммит
1257328aec
|
@ -408,8 +408,10 @@ type analysisNode struct {
|
|||
exportDeps map[PackagePath]*analysisNode // subset of allDeps ref'd by export data (+self)
|
||||
count int32 // number of unfinished successors
|
||||
summary *analyzeSummary // serializable result of analyzing this package
|
||||
typesOnce sync.Once // guards lazy population of types field
|
||||
|
||||
typesOnce sync.Once // guards lazy population of types and typesErr fields
|
||||
types *types.Package // type information lazily imported from summary
|
||||
typesErr error // an error producing type information
|
||||
}
|
||||
|
||||
func (an *analysisNode) String() string { return string(an.m.ID) }
|
||||
|
@ -417,7 +419,7 @@ func (an *analysisNode) String() string { return string(an.m.ID) }
|
|||
// _import imports this node's types.Package from export data, if not already done.
|
||||
// Precondition: analysis was a success.
|
||||
// Postcondition: an.types and an.exportDeps are populated.
|
||||
func (an *analysisNode) _import() *types.Package {
|
||||
func (an *analysisNode) _import() (*types.Package, error) {
|
||||
an.typesOnce.Do(func() {
|
||||
if an.m.PkgPath == "unsafe" {
|
||||
an.types = types.Unsafe
|
||||
|
@ -439,12 +441,19 @@ func (an *analysisNode) _import() *types.Package {
|
|||
}
|
||||
an.exportDeps[path] = dep // record, for later fact decoding
|
||||
if dep == an {
|
||||
if an.typesErr != nil {
|
||||
return an.typesErr
|
||||
} else {
|
||||
items[i].Pkg = an.types
|
||||
}
|
||||
} else {
|
||||
i := i
|
||||
g.Go(func() error {
|
||||
items[i].Pkg = dep._import()
|
||||
return nil
|
||||
depPkg, err := dep._import()
|
||||
if err == nil {
|
||||
items[i].Pkg = depPkg
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -452,13 +461,13 @@ func (an *analysisNode) _import() *types.Package {
|
|||
}
|
||||
pkg, err := gcimporter.IImportShallow(an.fset, getPackages, an.summary.Export, string(an.m.PkgPath))
|
||||
if err != nil {
|
||||
log.Fatalf("%s: invalid export data: %v", an.m, err)
|
||||
}
|
||||
if pkg != an.types {
|
||||
an.typesErr = bug.Errorf("%s: invalid export data: %v", an.m, err)
|
||||
an.types = nil
|
||||
} else if pkg != an.types {
|
||||
log.Fatalf("%s: inconsistent packages", an.m)
|
||||
}
|
||||
})
|
||||
return an.types
|
||||
return an.types, an.typesErr
|
||||
}
|
||||
|
||||
// analyzeSummary is a gob-serializable summary of successfully
|
||||
|
@ -703,8 +712,11 @@ func (an *analysisNode) run(ctx context.Context) (*analyzeSummary, error) {
|
|||
// Does the fact relate to a package referenced by export data?
|
||||
if dep, ok := allExportDeps[PackagePath(path)]; ok {
|
||||
dep.typesOnce.Do(func() { log.Fatal("dep.types not populated") })
|
||||
if dep.typesErr == nil {
|
||||
return dep.types
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the fact relates to a dependency not referenced
|
||||
// by export data, it is safe to ignore it.
|
||||
|
@ -867,7 +879,7 @@ func (an *analysisNode) typeCheck(parsed []*source.ParsedGoFile) *analysisPackag
|
|||
return nil, fmt.Errorf("invalid use of internal package %s", importPath)
|
||||
}
|
||||
|
||||
return dep._import(), nil
|
||||
return dep._import()
|
||||
}),
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче