From d529a24e2e0067efb60da1fcc5f1ab61439a9aef Mon Sep 17 00:00:00 2001 From: Daniel Cannon Date: Sun, 22 May 2016 22:59:54 +0100 Subject: [PATCH] Changed Connect to return the reason for connections --- CHANGELOG.md | 3 +++ cluster.go | 29 +++++++++++++++++++++++++---- session_test.go | 2 ++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5714fc8..f5d55fe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Changed + - Changed `Connect` to return the reason for connections failing (instead of just "no connections were made when creating the session") + ### Fixed - Fixed queries not being retried when using `Query()`, queries are now retried if the request failed due to a bad connection. - Fixed `Cursor` methods panicking if using a nil cursor, please note that you should still always check if your queries return an error. diff --git a/cluster.go b/cluster.go index 76ae6830..b92f139e 100644 --- a/cluster.go +++ b/cluster.go @@ -39,8 +39,12 @@ func NewCluster(hosts []Host, opts *ConnectOpts) (*Cluster, error) { opts: opts, } - //Check that hosts in the ClusterConfig is not empty - c.connectNodes(c.getSeeds()) + // Attempt to connect to each host and discover any additional hosts if host + // discovery is enabled + if err := c.connectNodes(c.getSeeds()); err != nil { + return nil, err + } + if !c.IsConnected() { return nil, ErrNoConnectionsStarted } @@ -206,17 +210,20 @@ func (c *Cluster) listenForNodeChanges() error { return err } -func (c *Cluster) connectNodes(hosts []Host) { +func (c *Cluster) connectNodes(hosts []Host) error { // Add existing nodes to map nodeSet := map[string]*Node{} for _, node := range c.GetNodes() { nodeSet[node.ID] = node } + var attemptErr error + // Attempt to connect to each seed host for _, host := range hosts { conn, err := NewConnection(host.String(), c.opts) if err != nil { + attemptErr = err Log.Warnf("Error creating connection: %s", err.Error()) continue } @@ -235,6 +242,7 @@ func (c *Cluster) connectNodes(hosts []Host) { _, cursor, err := conn.Query(q) if err != nil { + attemptErr = err Log.Warnf("Error fetching cluster status: %s", err) continue } @@ -242,6 +250,7 @@ func (c *Cluster) connectNodes(hosts []Host) { var results []nodeStatus err = cursor.All(&results) if err != nil { + attemptErr = err continue } @@ -256,12 +265,14 @@ func (c *Cluster) connectNodes(hosts []Host) { nodeSet[node.ID] = node } } else { + attemptErr = err Log.Warnf("Error connecting to node: %s", err) } } } else { svrRsp, err := conn.Server() if err != nil { + attemptErr = err Log.Warnf("Error fetching server ID: %s", err) continue } @@ -273,20 +284,30 @@ func (c *Cluster) connectNodes(hosts []Host) { "id": node.ID, "host": node.Host.String(), }).Debug("Connected to node") + nodeSet[node.ID] = node } } else { + attemptErr = err Log.Warnf("Error connecting to node: %s", err) } } } + // If no nodes were contactable then return the last error, this does not + // include driver errors such as if there was an issue building the + // query + if len(nodeSet) == 0 { + return attemptErr + } + nodes := []*Node{} for _, node := range nodeSet { nodes = append(nodes, node) } - c.setNodes(nodes) + + return nil } func (c *Cluster) connectNodeWithStatus(s nodeStatus) (*Node, error) { diff --git a/session_test.go b/session_test.go index 53b27de1..01396042 100644 --- a/session_test.go +++ b/session_test.go @@ -85,7 +85,9 @@ func (s *RethinkSuite) TestSessionConnectError(c *test.C) { Address: "nonexistanturl", Timeout: time.Second, }) + c.Assert(err, test.NotNil) + c.Assert(err, test.FitsTypeOf, RQLConnectionError{}) } func (s *RethinkSuite) TestSessionClose(c *test.C) {