Skip to content

Commit

Permalink
Merge pull request #132 from victor-perov/vic/add-more-info-to-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
DoubleDi committed Jun 29, 2021
2 parents 8cd7b32 + 2c0d310 commit 567d921
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 18 deletions.
14 changes: 8 additions & 6 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,17 @@ func (c *conn) doRequest(ctx context.Context, req *http.Request) (io.ReadCloser,
resp, err := transport.RoundTrip(req)
if err != nil {
c.cancel = nil
return nil, err
return nil, fmt.Errorf("doRequest: transport failed to send a request to ClickHouse: %w", err)
}
if resp.StatusCode != 200 {
msg, err := readResponse(resp)
c.cancel = nil
if err == nil {
err = newError(string(msg))
if err != nil {
return nil, fmt.Errorf("doRequest: failed to read the response with the status code %d: %w", resp.StatusCode, err)
}
return nil, err
// we got non-200 response, which means ClickHouse send an error in the
// response
return nil, newError(string(msg))
}
return resp.Body, nil
}
Expand All @@ -289,7 +291,7 @@ func (c *conn) buildRequest(ctx context.Context, query string, params []driver.V
var err error
if len(params) > 0 {
if query, err = interpolateParams(query, params); err != nil {
return nil, err
return nil, fmt.Errorf("buildRequest: failed to interpolate params: %w", err)
}
}

Expand All @@ -309,7 +311,7 @@ func (c *conn) buildRequest(ctx context.Context, query string, params []driver.V

req, err := http.NewRequest(http.MethodPost, c.url.String(), bodyReader)
if err != nil {
return nil, err
return nil, fmt.Errorf("buildRequest: failed to create a request: %w", err)
}

// http.Transport ignores url.User argument, handle it here
Expand Down
13 changes: 11 additions & 2 deletions conn_go18.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ package clickhouse
import (
"context"
"database/sql/driver"
"fmt"
"io/ioutil"
"strings"
)

// pingExpectedPrefix represents expected answer for "SELECT 1" query
const pingExpectedPrefix = "1"

// Ping implements the driver.Pinger
func (c *conn) Ping(ctx context.Context) error {
if c.transport == nil {
Expand All @@ -30,9 +34,14 @@ func (c *conn) Ping(ctx context.Context) error {

// Close response body to enable connection reuse
defer respBody.Close()

// drain the response body to check if we got expected `1`
resp, err := ioutil.ReadAll(respBody)
if err != nil || !strings.HasPrefix(string(resp), "1") {
return driver.ErrBadConn
if err != nil {
return fmt.Errorf("ping: failed to read the response: %w", err)
}
if !strings.HasPrefix(string(resp), pingExpectedPrefix) {
return fmt.Errorf("ping: failed to get expected result (1), got '%s' instead", string(resp))
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions conn_go18_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ func (s *connSuite) TestQueryContext() {
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(5*time.Millisecond, cancel)
_, err := s.conn.QueryContext(ctx, "SELECT sleep(3)")
s.EqualError(err, "context canceled")
s.EqualError(err, "doRequest: transport failed to send a request to ClickHouse: context canceled")
}

func (s *connSuite) TestExecContext() {
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(5*time.Millisecond, cancel)
_, err := s.conn.ExecContext(ctx, "SELECT sleep(3)")
s.EqualError(err, "context canceled")
s.EqualError(err, "doRequest: transport failed to send a request to ClickHouse: context canceled")
}

func (s *connSuite) TestPing() {
Expand Down
10 changes: 5 additions & 5 deletions rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,33 @@ func newTextRows(c *conn, body io.ReadCloser, location *time.Location, useDBLoca

columns, err := tsvReader.Read()
if err != nil {
return nil, err
return nil, fmt.Errorf("newTextRows: failed to parse the list of columns: %w", err)
}

types, err := tsvReader.Read()
if err != nil {
return nil, err
return nil, fmt.Errorf("newTextRows: failed to parse the list of column types: %w", err)
}
for i := range types {
types[i], err = readUnquoted(strings.NewReader(types[i]), 0)
if err != nil {
return nil, err
return nil, fmt.Errorf("newTextRows: failed to read the type '%s': %w", types[i], err)
}
}

parsers := make([]DataParser, len(types))
for i, typ := range types {
desc, err := ParseTypeDesc(typ)
if err != nil {
return nil, err
return nil, fmt.Errorf("newTextRows: failed to parse a description of the type '%s': %w", typ, err)
}

parsers[i], err = NewDataParser(desc, &DataParserOptions{
Location: location,
UseDBLocation: useDBLocation,
})
if err != nil {
return nil, err
return nil, fmt.Errorf("newTextRows: failed to create a data parser for the type '%s': %w", typ, err)
}
}

Expand Down
6 changes: 3 additions & 3 deletions stmt_go18_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (s *stmtSuite) TestQueryContext() {
s.Require().NoError(err)
time.AfterFunc(5*time.Millisecond, cancel)
_, err = st.QueryContext(ctx, 3)
s.EqualError(err, "context canceled")
s.EqualError(err, "doRequest: transport failed to send a request to ClickHouse: context canceled")
s.NoError(st.Close())
}

Expand All @@ -29,7 +29,7 @@ func (s *stmtSuite) TestExecContext() {
s.Require().NoError(err)
time.AfterFunc(5*time.Millisecond, cancel)
_, err = st.ExecContext(ctx, 3)
s.EqualError(err, "context canceled")
s.EqualError(err, "doRequest: transport failed to send a request to ClickHouse: context canceled")
s.NoError(st.Close())
}

Expand All @@ -41,6 +41,6 @@ func (s *stmtSuite) TestExecMultiContext() {
s.Require().NoError(err)
time.AfterFunc(10*time.Millisecond, cancel)
_, err = st.ExecContext(ctx, 3)
s.EqualError(err, "context canceled")
s.EqualError(err, "doRequest: transport failed to send a request to ClickHouse: context canceled")
s.NoError(st.Close())
}

0 comments on commit 567d921

Please sign in to comment.