fix(lsp): fix multiple bugs in lsp client lifecycle and handlers (#2305)

huaiyuWangh created

- Remove dead client from map when initialization fails to allow retry
- Use client's cwd field instead of os.Getwd() in openKeyConfigFiles
- Fix slog key-value pair in HandleServerMessage error logging
- Remove redundant hardcoded timeout in WaitForServerReady

Change summary

internal/lsp/client.go   | 11 +----------
internal/lsp/handlers.go |  2 +-
internal/lsp/manager.go  |  1 +
3 files changed, 3 insertions(+), 11 deletions(-)

Detailed changes

internal/lsp/client.go 🔗

@@ -277,10 +277,6 @@ func (c *Client) WaitForServerReady(ctx context.Context) error {
 	// Set initial state
 	c.SetServerState(StateStarting)
 
-	// Create a context with timeout
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
-	defer cancel()
-
 	// Try to ping the server with a simple request
 	ticker := time.NewTicker(500 * time.Millisecond)
 	defer ticker.Stop()
@@ -495,14 +491,9 @@ func (c *Client) RegisterServerRequestHandler(method string, handler transport.H
 
 // openKeyConfigFiles opens important configuration files that help initialize the server.
 func (c *Client) openKeyConfigFiles(ctx context.Context) {
-	wd, err := os.Getwd()
-	if err != nil {
-		return
-	}
-
 	// Try to open each file, ignoring errors if they don't exist
 	for _, file := range c.config.RootMarkers {
-		file = filepath.Join(wd, file)
+		file = filepath.Join(c.cwd, file)
 		if _, err := os.Stat(file); err == nil {
 			// File exists, try to open it
 			if err := c.OpenFile(ctx, file); err != nil {

internal/lsp/handlers.go 🔗

@@ -81,7 +81,7 @@ func notifyFileWatchRegistration(id string, watchers []protocol.FileSystemWatche
 func HandleServerMessage(_ context.Context, method string, params json.RawMessage) {
 	var msg protocol.ShowMessageParams
 	if err := json.Unmarshal(params, &msg); err != nil {
-		slog.Debug("Server message", "type", msg.Type, "message", msg.Message)
+		slog.Debug("Error unmarshal server message", "error", err)
 		return
 	}
 

internal/lsp/manager.go 🔗

@@ -229,6 +229,7 @@ func (s *Manager) startServer(ctx context.Context, name, filepath string, server
 	if _, err := client.Initialize(initCtx, s.cfg.WorkingDir()); err != nil {
 		slog.Error("LSP client initialization failed", "name", name, "error", err)
 		client.Close(ctx)
+		s.clients.Del(name)
 		return
 	}