internal/lsp: stop using structured errors
Using structured errors in gopls has proven to be difficult to manage:
it's hard to know whether a given error return is expected to be
structured without any type information. We have mostly eliminated
them; finish the job.
I don't intend any semantic changes here.
I considered eliminating CriticalError altogether, but it does seem
useful to have a convenient bundle for return values. So I left it
alone for now.
Change-Id: I4b5f85a8de9712babffbc1383088151b596bd815
Reviewed-on: https://go-review.googlesource.com/c/tools/+/287792
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 7bea58e..6a3995a 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -60,7 +60,7 @@
// initializedErr holds the last error resulting from initialization. If
// initialization fails, we only retry when the the workspace modules change,
// to avoid too many go/packages calls.
- initializedErr error
+ initializedErr *source.CriticalError
// mu guards all of the maps in the snapshot.
mu sync.Mutex
@@ -1012,7 +1012,7 @@
wsPkgs, _ := s.WorkspacePackages(ctx)
if msg := shouldShowAdHocPackagesWarning(s, wsPkgs); msg != "" {
return &source.CriticalError{
- MainError: fmt.Errorf(msg),
+ MainError: errors.New(msg),
}
}
// Even if workspace packages were returned, there still may be an error
@@ -1084,7 +1084,10 @@
// TODO(rstambler): Should we be more careful about returning the
// initialization error? Is it possible for the initialization error to be
// corrected without a successful reinitialization?
- return s.initializedErr
+ if s.initializedErr == nil {
+ return nil
+ }
+ return s.initializedErr.MainError
}
func (s *snapshot) AwaitInitialized(ctx context.Context) {
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index 5b767d1..55c52eb 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -9,7 +9,6 @@
"context"
"encoding/json"
"fmt"
- exec "golang.org/x/sys/execabs"
"io"
"io/ioutil"
"os"
@@ -23,6 +22,7 @@
"golang.org/x/mod/modfile"
"golang.org/x/mod/semver"
+ exec "golang.org/x/sys/execabs"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/gocommand"
@@ -581,7 +581,9 @@
ErrorList: modErrors,
}
} else {
- s.initializedErr = err
+ s.initializedErr = &source.CriticalError{
+ MainError: err,
+ }
}
} else {
// Clear out the initialization error, in case it had been set
diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go
index adf19ad..ceee5f0 100644
--- a/internal/lsp/diagnostics.go
+++ b/internal/lsp/diagnostics.go
@@ -350,13 +350,9 @@
// status bar.
var errMsg string
if err != nil {
- event.Error(ctx, "errors loading workspace", err, tag.Snapshot.Of(snapshot.ID()), tag.Directory.Of(snapshot.View().Folder()))
-
- // Some error messages can also be displayed as diagnostics.
- if criticalErr := (*source.CriticalError)(nil); errors.As(err, &criticalErr) {
- s.storeErrorDiagnostics(ctx, snapshot, modSource, criticalErr.ErrorList)
- }
- errMsg = strings.Replace(err.Error(), "\n", " ", -1)
+ event.Error(ctx, "errors loading workspace", err.MainError, tag.Snapshot.Of(snapshot.ID()), tag.Directory.Of(snapshot.View().Folder()))
+ s.storeErrorDiagnostics(ctx, snapshot, modSource, err.ErrorList)
+ errMsg = strings.Replace(err.MainError.Error(), "\n", " ", -1)
}
if s.criticalErrorStatus == nil {
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index 7a576a6d..2e0b851 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -556,17 +556,12 @@
}
type CriticalError struct {
+ // MainError is the primary error. Must be non-nil.
MainError error
+ // ErrorList contains any supplemental (structured) errors.
ErrorList []*Error
}
-func (err *CriticalError) Error() string {
- if err.MainError == nil {
- return ""
- }
- return err.MainError.Error()
-}
-
// An Error corresponds to an LSP Diagnostic.
// https://microsoft.github.io/language-server-protocol/specification#diagnostic
type Error struct {
@@ -601,13 +596,6 @@
UpgradeNotification
)
-func (e *Error) Error() string {
- if e.URI == "" {
- return e.Message
- }
- return fmt.Sprintf("%s:%s: %s", e.URI, e.Range, e.Message)
-}
-
var (
PackagesLoadError = errors.New("packages.Load error")
)