internal/lsp: suppress all errors when a view is loaded and checked

We were previously returning errors when we failed to load/check a
user's workspace folder, but now we suppress all errors. We shouldn't
disable gopls functionality if something is broken in a user's workspace
folder, rather, we should fall back to the file= queries that will run
when a user edits a file.

Change-Id: Iae05174ca80d2573c0222ac42f29e5556bda0134
Reviewed-on: https://go-review.googlesource.com/c/tools/+/209420
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go
index e544274..ef547bf 100644
--- a/internal/lsp/cache/check.go
+++ b/internal/lsp/cache/check.go
@@ -295,7 +295,7 @@
 	if pkg.pkgPath == "unsafe" {
 		pkg.types = types.Unsafe
 	} else if len(files) == 0 { // not the unsafe package, no parsed files
-		return nil, errors.Errorf("no parsed files for package %s", pkg.pkgPath)
+		return nil, errors.Errorf("no parsed files for package %s, expected: %s", pkg.pkgPath, pkg.compiledGoFiles)
 	} else {
 		pkg.types = types.NewPackage(string(m.pkgPath), m.name)
 	}
diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go
index ca5bfb4..d5045f6 100644
--- a/internal/lsp/cache/load.go
+++ b/internal/lsp/cache/load.go
@@ -34,8 +34,6 @@
 	config *packages.Config
 }
 
-var errNoPackagesFound = errors.New("no packages found for query")
-
 func (s *snapshot) load(ctx context.Context, scope source.Scope) ([]*metadata, error) {
 	uri := scope.URI()
 	var query string
@@ -67,7 +65,7 @@
 	log.Print(ctx, "go/packages.Load", tag.Of("packages", len(pkgs)))
 	if len(pkgs) == 0 {
 		if err == nil {
-			err = errNoPackagesFound
+			err = errors.Errorf("no packages found for query %s", query)
 		}
 	}
 	if err != nil {
diff --git a/internal/lsp/cache/parse.go b/internal/lsp/cache/parse.go
index 417d3ac..6dff423 100644
--- a/internal/lsp/cache/parse.go
+++ b/internal/lsp/cache/parse.go
@@ -47,6 +47,10 @@
 	err        error
 }
 
+func (pgh *parseGoHandle) String() string {
+	return pgh.File().Identity().URI.Filename()
+}
+
 func (c *cache) ParseGoHandle(fh source.FileHandle, mode source.ParseMode) source.ParseGoHandle {
 	key := parseKey{
 		file: fh.Identity(),
@@ -65,27 +69,27 @@
 	}
 }
 
-func (h *parseGoHandle) File() source.FileHandle {
-	return h.file
+func (pgh *parseGoHandle) File() source.FileHandle {
+	return pgh.file
 }
 
-func (h *parseGoHandle) Mode() source.ParseMode {
-	return h.mode
+func (pgh *parseGoHandle) Mode() source.ParseMode {
+	return pgh.mode
 }
 
-func (h *parseGoHandle) Parse(ctx context.Context) (*ast.File, *protocol.ColumnMapper, error, error) {
-	v := h.handle.Get(ctx)
+func (pgh *parseGoHandle) Parse(ctx context.Context) (*ast.File, *protocol.ColumnMapper, error, error) {
+	v := pgh.handle.Get(ctx)
 	if v == nil {
-		return nil, nil, nil, errors.Errorf("no parsed file for %s", h.File().Identity().URI)
+		return nil, nil, nil, errors.Errorf("no parsed file for %s", pgh.File().Identity().URI)
 	}
 	data := v.(*parseGoData)
 	return data.ast, data.mapper, data.parseError, data.err
 }
 
-func (h *parseGoHandle) Cached() (*ast.File, *protocol.ColumnMapper, error, error) {
-	v := h.handle.Cached()
+func (pgh *parseGoHandle) Cached() (*ast.File, *protocol.ColumnMapper, error, error) {
+	v := pgh.handle.Cached()
 	if v == nil {
-		return nil, nil, nil, errors.Errorf("no cached AST for %s", h.file.Identity().URI)
+		return nil, nil, nil, errors.Errorf("no cached AST for %s", pgh.file.Identity().URI)
 	}
 	data := v.(*parseGoData)
 	return data.ast, data.mapper, data.parseError, data.err
diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go
index 677ae56..062df68 100644
--- a/internal/lsp/cache/session.go
+++ b/internal/lsp/cache/session.go
@@ -6,7 +6,6 @@
 
 import (
 	"context"
-	"fmt"
 	"path/filepath"
 	"sort"
 	"strconv"
@@ -18,6 +17,7 @@
 	"golang.org/x/tools/internal/lsp/source"
 	"golang.org/x/tools/internal/lsp/telemetry"
 	"golang.org/x/tools/internal/span"
+	"golang.org/x/tools/internal/telemetry/log"
 	"golang.org/x/tools/internal/telemetry/trace"
 	"golang.org/x/tools/internal/xcontext"
 	errors "golang.org/x/xerrors"
@@ -136,9 +136,10 @@
 	v.snapshotMu.Lock()
 	defer v.snapshotMu.Unlock() // The code after the snapshot is used isn't expensive.
 	m, err := v.snapshot.load(ctx, source.DirectoryURI(folder))
-	var loadErr error
-	if err != nil && err != errNoPackagesFound {
-		loadErr = fmt.Errorf("error loading packages: %v", err)
+	if err != nil {
+		// Suppress all errors.
+		log.Error(ctx, "failed to load snapshot", err, telemetry.Directory.Of(folder))
+		return v, nil, nil
 	}
 
 	// Prepare CheckPackageHandles for every package that's been loaded.
@@ -146,11 +147,13 @@
 	// been loaded has an existing checkPackageHandle.
 	phs, err := v.snapshot.checkWorkspacePackages(ctx, m)
 	if err != nil {
-		return nil, nil, err
+		// Suppress all errors.
+		log.Error(ctx, "failed to check snapshot", err, telemetry.Directory.Of(folder))
+		return v, nil, nil
 	}
 
 	debug.AddView(debugView{v})
-	return v, phs, loadErr
+	return v, phs, nil
 }
 
 // View returns the view by name.