resolves issues where failed api calls lead to obscure errors (#7051)

This commit is contained in:
Steven Soroka 2020-02-19 21:46:08 -05:00 committed by GitHub
parent 3058308d38
commit 5023df08d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 97 additions and 16 deletions

View File

@ -210,6 +210,7 @@ func (ro *RunningOutput) WriteBatch() error {
return nil return nil
} }
// Close closes the output
func (r *RunningOutput) Close() { func (r *RunningOutput) Close() {
err := r.Output.Close() err := r.Output.Close()
if err != nil { if err != nil {

View File

@ -1,6 +1,9 @@
package ecs package ecs
import ( import (
"fmt"
"io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
@ -50,10 +53,16 @@ func (c *EcsClient) Task() (*Task, error) {
req, _ := http.NewRequest("GET", c.taskURL, nil) req, _ := http.NewRequest("GET", c.taskURL, nil)
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 200))
return nil, fmt.Errorf("%s returned HTTP status %s: %q", c.taskURL, resp.Status, body)
}
task, err := unmarshalTask(resp.Body) task, err := unmarshalTask(resp.Body)
if err != nil { if err != nil {
@ -71,11 +80,18 @@ func (c *EcsClient) ContainerStats() (map[string]types.StatsJSON, error) {
req, _ := http.NewRequest("GET", c.statsURL, nil) req, _ := http.NewRequest("GET", c.statsURL, nil)
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
return map[string]types.StatsJSON{}, err return map[string]types.StatsJSON{}, err
} }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 200))
return nil, fmt.Errorf("%s returned HTTP status %s: %q", c.statsURL, resp.Status, body)
}
statsMap, err := unmarshalStats(resp.Body) statsMap, err := unmarshalStats(resp.Body)
if err != nil { if err != nil {
return map[string]types.StatsJSON{}, err return map[string]types.StatsJSON{}, err

View File

@ -107,6 +107,7 @@ func TestEcsClient_Task(t *testing.T) {
client: mockDo{ client: mockDo{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {
return &http.Response{ return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(rc), Body: ioutil.NopCloser(rc),
}, nil }, nil
}, },
@ -123,10 +124,23 @@ func TestEcsClient_Task(t *testing.T) {
wantErr: true, wantErr: true,
}, },
{ {
name: "malformed resp", name: "malformed 500 resp",
client: mockDo{ client: mockDo{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {
return &http.Response{ return &http.Response{
StatusCode: http.StatusInternalServerError,
Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
wantErr: true,
},
{
name: "malformed 200 resp",
client: mockDo{
do: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))), Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil }, nil
}, },
@ -164,6 +178,7 @@ func TestEcsClient_ContainerStats(t *testing.T) {
client: mockDo{ client: mockDo{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {
return &http.Response{ return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(rc), Body: ioutil.NopCloser(rc),
}, nil }, nil
}, },
@ -181,10 +196,11 @@ func TestEcsClient_ContainerStats(t *testing.T) {
wantErr: true, wantErr: true,
}, },
{ {
name: "malformed resp", name: "malformed 200 resp",
client: mockDo{ client: mockDo{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {
return &http.Response{ return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))), Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil }, nil
}, },
@ -192,6 +208,19 @@ func TestEcsClient_ContainerStats(t *testing.T) {
want: map[string]types.StatsJSON{}, want: map[string]types.StatsJSON{},
wantErr: true, wantErr: true,
}, },
{
name: "malformed 500 resp",
client: mockDo{
do: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusInternalServerError,
Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
want: nil,
wantErr: true,
},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@ -97,6 +97,7 @@ func (f *Fibaro) getJSON(path string, dataStruct interface{}) error {
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("Response from url \"%s\" has status code %d (%s), expected %d (%s)", err = fmt.Errorf("Response from url \"%s\" has status code %d (%s), expected %d (%s)",
@ -108,8 +109,6 @@ func (f *Fibaro) getJSON(path string, dataStruct interface{}) error {
return err return err
} }
defer resp.Body.Close()
dec := json.NewDecoder(resp.Body) dec := json.NewDecoder(resp.Body)
err = dec.Decode(&dataStruct) err = dec.Decode(&dataStruct)
if err != nil { if err != nil {

View File

@ -181,6 +181,7 @@ func (g *haproxy) gatherServer(addr string, acc telegraf.Accumulator) error {
if err != nil { if err != nil {
return fmt.Errorf("Unable to connect to haproxy server '%s': %s", addr, err) return fmt.Errorf("Unable to connect to haproxy server '%s': %s", addr, err)
} }
defer res.Body.Close()
if res.StatusCode != 200 { if res.StatusCode != 200 {
return fmt.Errorf("Unable to get valid stat result from '%s', http response code : %d", addr, res.StatusCode) return fmt.Errorf("Unable to get valid stat result from '%s', http response code : %d", addr, res.StatusCode)

View File

@ -3,6 +3,8 @@ package kibana
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -250,6 +252,12 @@ func (k *Kibana) gatherJsonData(url string, v interface{}) (host string, err err
defer response.Body.Close() defer response.Body.Close()
if response.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(response.Body, 200))
return request.Host, fmt.Errorf("%s returned HTTP status %s: %q", url, response.Status, body)
}
if err = json.NewDecoder(response.Body).Decode(v); err != nil { if err = json.NewDecoder(response.Body).Decode(v); err != nil {
return request.Host, err return request.Host, err
} }

View File

@ -3,6 +3,8 @@ package logstash
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -197,6 +199,11 @@ func (logstash *Logstash) gatherJsonData(url string, value interface{}) error {
} }
defer response.Body.Close() defer response.Body.Close()
if response.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(response.Body, 200))
return fmt.Errorf("%s returned HTTP status %s: %q", url, response.Status, body)
}
err = json.NewDecoder(response.Body).Decode(value) err = json.NewDecoder(response.Body).Decode(value)
if err != nil { if err != nil {

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@ -143,6 +144,12 @@ func runChimp(api *ChimpAPI, params ReportsParams) ([]byte, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 200))
return nil, fmt.Errorf("%s returned HTTP status %s: %q", api.url.String(), resp.Status, body)
}
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -2,14 +2,18 @@ package nginx_upstream_check
import ( import (
"encoding/json" "encoding/json"
"github.com/influxdata/telegraf" "fmt"
"github.com/influxdata/telegraf/internal" "io"
"github.com/influxdata/telegraf/internal/tls" "io/ioutil"
"github.com/influxdata/telegraf/plugins/inputs"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"time" "time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/internal/tls"
"github.com/influxdata/telegraf/plugins/inputs"
) )
const sampleConfig = ` const sampleConfig = `
@ -148,6 +152,11 @@ func (check *NginxUpstreamCheck) gatherJsonData(url string, value interface{}) e
} }
defer response.Body.Close() defer response.Body.Close()
if response.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(response.Body, 200))
return fmt.Errorf("%s returned HTTP status %s: %q", url, response.Status, body)
}
err = json.NewDecoder(response.Body).Decode(value) err = json.NewDecoder(response.Body).Decode(value)
if err != nil { if err != nil {

View File

@ -51,8 +51,6 @@ func TestReadsMetricsFromNSQ(t *testing.T) {
assert.Equal(t, 0, len(acc.Metrics), "There should not be any points") assert.Equal(t, 0, len(acc.Metrics), "There should not be any points")
if err := consumer.Start(&acc); err != nil { if err := consumer.Start(&acc); err != nil {
t.Fatal(err.Error()) t.Fatal(err.Error())
} else {
defer consumer.Stop()
} }
waitForPoint(&acc, t) waitForPoint(&acc, t)

View File

@ -5,6 +5,7 @@ import (
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
@ -200,6 +201,11 @@ func (s *Salesforce) login() error {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// ignore the err here; LimitReader returns io.EOF and we're not interested in read errors.
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 200))
return fmt.Errorf("%s returned HTTP status %s: %q", loginEndpoint, resp.Status, body)
}
respBody, err := ioutil.ReadAll(resp.Body) respBody, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {