-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create write/Error wrapper to better handle http/Error with Hea…
…ders.
- Loading branch information
1 parent
4e3ff5f
commit af74d7a
Showing
6 changed files
with
145 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2020-2024 InfluxData, Inc. All rights reserved. | ||
// Use of this source code is governed by MIT | ||
// license that can be found in the LICENSE file. | ||
|
||
package write | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"github.com/influxdata/influxdb-client-go/v2/api/http" | ||
iHttp "net/http" | ||
"net/textproto" | ||
) | ||
|
||
// Error wraps an error that may have occurred during a write call. Most often this will be an http.Error. | ||
type Error struct { | ||
origin error | ||
message string | ||
} | ||
|
||
// NewError returns a new created Error instance wrapping the original error. | ||
func NewError(origin error, message string) *Error { | ||
return &Error{ | ||
origin: origin, | ||
message: message, | ||
} | ||
} | ||
|
||
// Error fulfills the error interface | ||
func (e *Error) Error() string { | ||
return fmt.Sprintf("%s:\n %s", e.message, e.origin) | ||
} | ||
|
||
func (e *Error) Unwrap() error { | ||
return e.origin | ||
} | ||
|
||
// HTTPHeader returns the Header of a wrapped http.Error. If the original error is not http.Error returns standard error. | ||
func (e *Error) HTTPHeader() (iHttp.Header, error) { | ||
var err *http.Error | ||
ok := errors.As(e.origin, &err) | ||
if ok { | ||
return err.Header, nil | ||
} | ||
return nil, fmt.Errorf(fmt.Sprintf("Origin error: (%s) is not of type *http.Error.\n", e.origin.Error())) | ||
} | ||
|
||
// GetHeaderValues returns the values from a Header key. If original error is not http.Error return standard error. | ||
func (e *Error) GetHeaderValues(key string) ([]string, error) { | ||
var err *http.Error | ||
if errors.As(e.origin, &err) { | ||
return err.Header.Values(textproto.CanonicalMIMEHeaderKey(key)), nil | ||
} | ||
return nil, fmt.Errorf(fmt.Sprintf("Origin error: (%s) is not of type http.Header.\n", e.origin.Error())) | ||
} | ||
|
||
// GetHeader returns the first value from a header key. If origin is not http.Error or if no match is found returns "". | ||
func (e *Error) GetHeader(key string) string { | ||
var err *http.Error | ||
if errors.As(e.origin, &err) { | ||
return err.Header.Get(textproto.CanonicalMIMEHeaderKey(key)) | ||
} | ||
return "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2020-2024 InfluxData, Inc. All rights reserved. | ||
// Use of this source code is governed by MIT | ||
// license that can be found in the LICENSE file. | ||
|
||
package write | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"github.com/influxdata/influxdb-client-go/v2/api/http" | ||
"github.com/stretchr/testify/assert" | ||
ihttp "net/http" | ||
"testing" | ||
) | ||
|
||
func TestNewErrorNotHttpError(t *testing.T) { | ||
err := NewError(fmt.Errorf("origin error"), "error message") | ||
var errTest *http.Error | ||
assert.False(t, errors.As(err, &errTest)) | ||
header, okh := err.HTTPHeader() | ||
assert.Nil(t, header) | ||
assert.Error(t, okh) | ||
values, okv := err.GetHeaderValues("Date") | ||
assert.Nil(t, values) | ||
assert.Error(t, okv) | ||
assert.Equal(t, "", err.GetHeader("Date")) | ||
assert.Equal(t, "error message:\n origin error", err.Error()) | ||
} | ||
|
||
func TestNewErrorHttpError(t *testing.T) { | ||
header := ihttp.Header{ | ||
"Date": []string{"2024-08-07T12:00:00.009"}, | ||
"Content-Length": []string{"12"}, | ||
"Content-Type": []string{"application/json", "encoding UTF-8"}, | ||
"X-Test-Value1": []string{"SaturnV"}, | ||
"X-Test-Value2": []string{"Apollo11"}, | ||
"Retry-After": []string{"2044"}, | ||
"Trace-Id": []string{"123456789ABCDEF0"}, | ||
} | ||
|
||
err := NewError(&http.Error{ | ||
StatusCode: ihttp.StatusBadRequest, | ||
Code: "bad request", | ||
Message: "this is just a test", | ||
Err: nil, | ||
RetryAfter: 2044, | ||
Header: header, | ||
}, "should be httpError") | ||
|
||
var errTest *http.Error | ||
assert.True(t, errors.As(err.Unwrap(), &errTest)) | ||
header, okh := err.HTTPHeader() | ||
assert.NotNil(t, header) | ||
assert.Nil(t, okh) | ||
date, okd := err.GetHeaderValues("Date") | ||
assert.Equal(t, []string{"2024-08-07T12:00:00.009"}, date) | ||
assert.Nil(t, okd) | ||
cType, okc := err.GetHeaderValues("Content-Type") | ||
assert.Equal(t, []string{"application/json", "encoding UTF-8"}, cType) | ||
assert.Nil(t, okc) | ||
assert.Equal(t, "2024-08-07T12:00:00.009", err.GetHeader("Date")) | ||
assert.Equal(t, "SaturnV", err.GetHeader("X-Test-Value1")) | ||
assert.Equal(t, "Apollo11", err.GetHeader("X-Test-Value2")) | ||
assert.Equal(t, "123456789ABCDEF0", err.GetHeader("Trace-Id")) | ||
assert.Equal(t, "should be httpError:\n bad request: this is just a test", err.Error()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters