Skip to content

Commit 7e11c94

Browse files
authored
Merge pull request #19 from sqlrsync/showConnectError
feat: improve client error reporting from server
2 parents 1715b65 + 679cc05 commit 7e11c94

File tree

2 files changed

+105
-7
lines changed

2 files changed

+105
-7
lines changed

client/remote/client.go

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,58 @@ func (c *Client) Connect() error {
703703

704704
conn, response, err := dialer.DialContext(connectCtx, u.String(), headers)
705705
if err != nil {
706-
if response != nil && response.Body != nil {
707-
respStr, _ := io.ReadAll(response.Body)
708-
response.Body.Close()
709-
return fmt.Errorf("%s", respStr)
706+
if response != nil {
707+
// Extract detailed error information from the response
708+
statusCode := response.StatusCode
709+
statusText := response.Status
710+
711+
var respBodyStr string
712+
if response.Body != nil {
713+
respBytes, readErr := io.ReadAll(response.Body)
714+
response.Body.Close()
715+
if readErr == nil {
716+
respBodyStr = strings.TrimSpace(string(respBytes))
717+
}
718+
}
719+
720+
// Create a clean error message
721+
var errorMsg strings.Builder
722+
errorMsg.WriteString(fmt.Sprintf("HTTP %d (%s)", statusCode, statusText))
723+
724+
if respBodyStr != "" {
725+
errorMsg.WriteString(fmt.Sprintf(": %s", respBodyStr))
726+
}
727+
728+
return fmt.Errorf("%s", errorMsg.String())
729+
}
730+
731+
// Handle cases where response is nil (e.g., network errors, bad handshake)
732+
var errorMsg strings.Builder
733+
errorMsg.WriteString("Failed to connect to WebSocket")
734+
735+
// Analyze the error type and provide helpful context
736+
errorStr := err.Error()
737+
if strings.Contains(errorStr, "bad handshake") {
738+
errorMsg.WriteString(" - WebSocket handshake failed")
739+
errorMsg.WriteString("\nThis could be due to:")
740+
errorMsg.WriteString("\n• Invalid server URL or endpoint")
741+
errorMsg.WriteString("\n• Server not supporting WebSocket connections")
742+
errorMsg.WriteString("\n• Network connectivity issues")
743+
errorMsg.WriteString("\n• Authentication problems")
744+
} else if strings.Contains(errorStr, "timeout") {
745+
errorMsg.WriteString(" - Connection timeout")
746+
errorMsg.WriteString("\nThe server may be overloaded or unreachable")
747+
} else if strings.Contains(errorStr, "refused") {
748+
errorMsg.WriteString(" - Connection refused")
749+
errorMsg.WriteString("\nThe server may be down or the port may be blocked")
750+
} else if strings.Contains(errorStr, "no such host") {
751+
errorMsg.WriteString(" - DNS resolution failed")
752+
errorMsg.WriteString("\nCheck the server hostname in your configuration")
710753
}
711-
return fmt.Errorf("failed to connect to WebSocket: %w", err)
754+
755+
errorMsg.WriteString(fmt.Sprintf("\nOriginal error: %v", err))
756+
757+
return fmt.Errorf("%s", errorMsg.String())
712758
}
713759
defer response.Body.Close()
714760

client/subscription/manager.go

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"io"
78
"net/http"
89
"net/url"
910
"strings"
@@ -207,9 +208,60 @@ func (m *Manager) doConnect() error {
207208

208209
m.logger.Debug("Dialing WebSocket", zap.String("url", u.String()))
209210

210-
conn, _, err := dialer.DialContext(m.ctx, u.String(), headers)
211+
conn, response, err := dialer.DialContext(m.ctx, u.String(), headers)
211212
if err != nil {
212-
return fmt.Errorf("failed to connect to subscription service: %w", err)
213+
if response != nil {
214+
// Extract detailed error information from the response
215+
statusCode := response.StatusCode
216+
statusText := response.Status
217+
218+
var respBodyStr string
219+
if response.Body != nil {
220+
respBytes, readErr := io.ReadAll(response.Body)
221+
response.Body.Close()
222+
if readErr == nil {
223+
respBodyStr = strings.TrimSpace(string(respBytes))
224+
}
225+
}
226+
227+
// Create a clean error message
228+
var errorMsg strings.Builder
229+
errorMsg.WriteString(fmt.Sprintf("HTTP %d (%s)", statusCode, statusText))
230+
231+
if respBodyStr != "" {
232+
errorMsg.WriteString(fmt.Sprintf(": %s", respBodyStr))
233+
}
234+
235+
return fmt.Errorf("%s", errorMsg.String())
236+
}
237+
238+
// Handle cases where response is nil (e.g., network errors, bad handshake)
239+
var errorMsg strings.Builder
240+
errorMsg.WriteString("Failed to connect to subscription service")
241+
242+
// Analyze the error type and provide helpful context
243+
errorStr := err.Error()
244+
if strings.Contains(errorStr, "bad handshake") {
245+
errorMsg.WriteString(" - WebSocket handshake failed")
246+
errorMsg.WriteString("\nThis could be due to:")
247+
errorMsg.WriteString("\n• Invalid server URL or endpoint")
248+
errorMsg.WriteString("\n• Server not supporting WebSocket connections")
249+
errorMsg.WriteString("\n• Network connectivity issues")
250+
errorMsg.WriteString("\n• Authentication problems")
251+
} else if strings.Contains(errorStr, "timeout") {
252+
errorMsg.WriteString(" - Connection timeout")
253+
errorMsg.WriteString("\nThe server may be overloaded or unreachable")
254+
} else if strings.Contains(errorStr, "refused") {
255+
errorMsg.WriteString(" - Connection refused")
256+
errorMsg.WriteString("\nThe server may be down or the port may be blocked")
257+
} else if strings.Contains(errorStr, "no such host") {
258+
errorMsg.WriteString(" - DNS resolution failed")
259+
errorMsg.WriteString("\nCheck the server hostname in your configuration")
260+
}
261+
262+
errorMsg.WriteString(fmt.Sprintf("\nOriginal error: %v", err))
263+
264+
return fmt.Errorf("%s", errorMsg.String())
213265
}
214266

215267
m.mu.Lock()

0 commit comments

Comments
 (0)