-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: HTTP headers in Error type #404
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #404 +/- ##
==========================================
+ Coverage 92.94% 92.99% +0.04%
==========================================
Files 25 25
Lines 2310 2326 +16
==========================================
+ Hits 2147 2163 +16
Misses 123 123
Partials 40 40 ☔ View full report in Codecov by Sentry. |
api/write_test.go
Outdated
assert.Equal(t, calls, 3) | ||
} | ||
|
||
func TestWriteErrorHeaderToString(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a unit test for http.Error
. Move this to error_test.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored to error_test.go
internal/write/service.go
Outdated
@@ -164,6 +164,7 @@ func (w *Service) HandleWrite(ctx context.Context, batch *Batch) error { | |||
if batchToWrite != nil { | |||
perror := w.WriteBatch(ctx, batchToWrite) | |||
if perror != nil { | |||
// fmt.Printf("DEBUG perror type %s\n", reflect.TypeOf(perror)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed.
internal/write/service.go
Outdated
"X-Influxdb-Version", | ||
}) | ||
if len(logHeaders) > 0 { | ||
logMessage += fmt.Sprintf("\nSelect Response Headers:\n%s", logHeaders) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logMessage += fmt.Sprintf("\nSelect Response Headers:\n%s", logHeaders) | |
logMessage += fmt.Sprintf("\nSelected Response Headers:\n%s", logHeaders) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "Selected"
internal/write/service_test.go
Outdated
//fmt.Printf("DEBUG err %v\n", err) | ||
//fmt.Printf("DEBUG err %v\n", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
internal/write/service_test.go
Outdated
require.NotNil(t, err) | ||
// 1st Batch expires and writing 2nd trows error | ||
assert.Equal(t, "write failed (attempts 1): Unexpected status code 429", err.Error()) | ||
assert.Equal(t, 1, srv.retryQueue.list.Len()) | ||
// fmt.Printf("DEBUG Header len: %d\n", len(err.(*http.Error).Header)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
internal/write/service.go
Outdated
return &http2.Error{ | ||
StatusCode: int(perror.StatusCode), | ||
Code: perror.Code, | ||
Message: fmt.Errorf( | ||
"write failed (attempts %d): %w", batchToWrite.RetryAttempts, perror, | ||
).Error(), | ||
Err: perror.Err, | ||
RetryAfter: perror.RetryAfter, | ||
Header: perror.Header, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look good from the API perspective to return http.Error
from the write service. And the more serious problem is that the final message looks silly: "400 Bad Request: write failed (attempts 0): 400 Bad Request: { \"code\": \"bad request\", \"message\": \"test header\"
.
The solution could be to create a write error that would wrap the previous:
package write
type Error struct {
origin error
message string
}
func NewError(err error, message string) *Error {
return &Error{
origin: err,
message: message,
}
}
func (e *Error) Error() string {
return fmt.Sprintf("%s: %s", e.message, e.origin)
}
func (e *Error) Unwrap() error {
return e.origin
}
Then this code would be:
return write.NewError(perror, fmt.Sprintf("write failed (attempts %d)", batchToWrite.RetryAttempts))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. When I wrote it, I was thinking there has to be a more elegant way of implementing this. I'm still fairly new to golang and the suggested solution did not occur to me. Implemented as suggested, and with helper methods for extracting header values.
…ttp.Error.Error() response.
…b-client-go into feat/httpErrorHeaders
api/http/error_test.go
Outdated
err := Error{ | ||
StatusCode: test.statusCode, | ||
Code: test.code, | ||
Message: test.message, | ||
Err: test.err, | ||
RetryAfter: 0, | ||
Header: ihttp.Header{}, | ||
} | ||
assert.Equal(t, test.expected, err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use t.Run()
construct for data-driven test (also add a test name to the table)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored using t.Run()
api/write/error.go
Outdated
"errors" | ||
"fmt" | ||
"github.com/influxdata/influxdb-client-go/v2/api/http" | ||
iHttp "net/http" | ||
"net/textproto" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use go imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file removed
api/write/error_test.go
Outdated
"errors" | ||
"fmt" | ||
"github.com/influxdata/influxdb-client-go/v2/api/http" | ||
"github.com/stretchr/testify/assert" | ||
ihttp "net/http" | ||
"testing" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use go imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file removed
"fmt" | ||
"io" | ||
"math" | ||
ihttp "net/http" | ||
"net/http/httptest" | ||
"runtime" | ||
"strconv" | ||
"strings" | ||
"sync" | ||
"testing" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use go imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
activated goimports
in IDE. Updated.
internal/write/service.go
Outdated
} | ||
return fmt.Errorf("write failed (attempts %d): %w", batchToWrite.RetryAttempts, perror) | ||
return write.NewError(perror, fmt.Sprintf("write failed (retry attempts %d)", batchToWrite.RetryAttempts)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry for the previous suggestion which now looks misleading. I looked at WriteAPI and WriteBlockingAPI and also at several issues regarding complaints about errors. The best solution will be to return perror
, and log a message about attempts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now logs failed attempt count and status code before returning perror
directly.
|
||
### Features | ||
|
||
- [#404](https://github.com/influxdata/influxdb-client-go/pull/404) Expose HTTP response headers in the Error type to aid analysis and debugging of error results. Add selected response headers to the error log. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- [#404](https://github.com/influxdata/influxdb-client-go/pull/404) Expose HTTP response headers in the Error type to aid analysis and debugging of error results. Add selected response headers to the error log. | |
- [#404](https://github.com/influxdata/influxdb-client-go/pull/404) Expose HTTP response headers in the Error type to aid analysis and debugging of error results. Add selected response headers to the error log. | |
Also, unified errors returned by WriteAPI, which now always returns `http.Error` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement 👍
Good job!
Proposed Changes
http.Header
asHeader
property toapi/http/Error
type to expose response headers for analysis and debugging.api/http/service,go
.Checklist