From 954445efd27c48711d07dc683c83ef0979d0585a Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Fri, 9 Sep 2016 17:55:36 -0500 Subject: [PATCH] Read an invalid JSON response as an error in the influx client --- CHANGELOG.md | 1 + client/influxdb.go | 34 +++++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e46b565d43..a88f31e052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#7270](https://github.com/influxdata/influxdb/issues/7270): Implement time math for lazy time literals. - [#7272](https://github.com/influxdata/influxdb/issues/7272): Report cmdline and memstats in /debug/vars. - [#7299](https://github.com/influxdata/influxdb/ssues/7299): Ensure fieldsCreated stat available in shard measurement. +- [#6846](https://github.com/influxdata/influxdb/issues/6846): Read an invalid JSON response as an error in the influx client. ## v1.0.0 [2016-09-07] diff --git a/client/influxdb.go b/client/influxdb.go index 90695b9ed2..0d42cf0bac 100644 --- a/client/influxdb.go +++ b/client/influxdb.go @@ -498,17 +498,36 @@ func (r *Response) Error() error { return nil } +// duplexReader reads responses and writes it to another writer while +// satisfying the reader interface. +type duplexReader struct { + r io.Reader + w io.Writer +} + +func (r *duplexReader) Read(p []byte) (n int, err error) { + n, err = r.r.Read(p) + if err == nil { + r.w.Write(p[:n]) + } + return n, err +} + // ChunkedResponse represents a response from the server that // uses chunking to stream the output. type ChunkedResponse struct { - dec *json.Decoder + dec *json.Decoder + duplex *duplexReader + buf bytes.Buffer } // NewChunkedResponse reads a stream and produces responses from the stream. func NewChunkedResponse(r io.Reader) *ChunkedResponse { - dec := json.NewDecoder(r) - dec.UseNumber() - return &ChunkedResponse{dec: dec} + resp := &ChunkedResponse{} + resp.duplex = &duplexReader{r: r, w: &resp.buf} + resp.dec = json.NewDecoder(resp.duplex) + resp.dec.UseNumber() + return resp } // NextResponse reads the next line of the stream and returns a response. @@ -518,8 +537,13 @@ func (r *ChunkedResponse) NextResponse() (*Response, error) { if err == io.EOF { return nil, nil } - return nil, err + // A decoding error happened. This probably means the server crashed + // and sent a last-ditch error message to us. Ensure we have read the + // entirety of the connection to get any remaining error text. + io.Copy(ioutil.Discard, r.duplex) + return nil, errors.New(strings.TrimSpace(r.buf.String())) } + r.buf.Reset() return &response, nil }