Skip to content

Commit 6148921

Browse files
author
Dean Karn
authored
Pass resp on retryable status (#31)
1 parent 9fe94b7 commit 6148921

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [5.17.1] - 2023-05-09
10+
### Fixed
11+
- ErrRetryableStatusCode passing the *http.Response to have access to not only the status code but headers etc. related to retrying.
12+
- Added ErrUnexpectedResponse to pass back when encountering an unexpected response code to allow the caller to decide what to do.
13+
914
## [5.17.0] - 2023-05-08
1015
### Added
1116
- bytesext.Bytes alias to int64 for better code clarity.
@@ -37,7 +42,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3742
### Added
3843
- Added `timext.NanoTime` for fast low level monotonic time with nanosecond precision.
3944

40-
[Unreleased]: https://github.com/go-playground/pkg/compare/v5.17.0...HEAD
45+
[Unreleased]: https://github.com/go-playground/pkg/compare/v5.17.1...HEAD
46+
[5.17.1]: https://github.com/go-playground/pkg/compare/v5.17.0...v5.17.1
4147
[5.17.0]: https://github.com/go-playground/pkg/compare/v5.16.0...v5.17.0
4248
[5.16.0]: https://github.com/go-playground/pkg/compare/v5.15.2...v5.16.0
4349
[5.15.2]: https://github.com/go-playground/pkg/compare/v5.15.1...v5.15.2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pkg
22

3-
![Project status](https://img.shields.io/badge/version-5.17.0-green.svg)
3+
![Project status](https://img.shields.io/badge/version-5.17.1-green.svg)
44
[![Lint & Test](https://github.com/go-playground/pkg/actions/workflows/go.yml/badge.svg)](https://github.com/go-playground/pkg/actions/workflows/go.yml)
55
[![Coverage Status](https://coveralls.io/repos/github/go-playground/pkg/badge.svg?branch=master)](https://coveralls.io/github/go-playground/pkg?branch=master)
66
[![GoDoc](https://godoc.org/github.com/go-playground/pkg?status.svg)](https://pkg.go.dev/mod/github.com/go-playground/pkg/v5)

net/http/retryable.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import (
88
"fmt"
99
bytesext "github.com/go-playground/pkg/v5/bytes"
1010
errorsext "github.com/go-playground/pkg/v5/errors"
11-
ioext "github.com/go-playground/pkg/v5/io"
1211
resultext "github.com/go-playground/pkg/v5/values/result"
13-
"io"
1412
"net/http"
1513
"strconv"
1614
)
@@ -33,11 +31,20 @@ var (
3331

3432
// ErrRetryableStatusCode can be used to indicate a retryable HTTP status code was encountered as an error.
3533
type ErrRetryableStatusCode struct {
36-
StatusCode int
34+
Response *http.Response
3735
}
3836

3937
func (e ErrRetryableStatusCode) Error() string {
40-
return fmt.Sprintf("retryable HTTP status code encountered: %d", e.StatusCode)
38+
return fmt.Sprintf("retryable HTTP status code encountered: %d", e.Response.StatusCode)
39+
}
40+
41+
// ErrUnexpectedResponse can be used to indicate an unexpected response was encountered as an error and provide access to the *http.Response.
42+
type ErrUnexpectedResponse struct {
43+
Response *http.Response
44+
}
45+
46+
func (e ErrUnexpectedResponse) Error() string {
47+
return "unexpected response encountered"
4148
}
4249

4350
// IsRetryableStatusCode returns if the provided status code is considered retryable.
@@ -77,7 +84,7 @@ func DoRetryableResponse(ctx context.Context, onRetryFn errorsext.OnRetryFn[erro
7784
}
7885

7986
if isRetryableStatusCode(resp.StatusCode) {
80-
opt := onRetryFn(ctx, ErrRetryableStatusCode{StatusCode: resp.StatusCode}, strconv.Itoa(resp.StatusCode), attempt)
87+
opt := onRetryFn(ctx, ErrRetryableStatusCode{Response: resp}, strconv.Itoa(resp.StatusCode), attempt)
8188
if opt.IsSome() {
8289
return resultext.Err[*http.Response, error](opt.Unwrap())
8390
}
@@ -106,9 +113,7 @@ func DoRetryable[T any](ctx context.Context, isRetryableFn errorsext.IsRetryable
106113
defer resp.Body.Close()
107114

108115
if resp.StatusCode != expectedResponseCode {
109-
b, _ := io.ReadAll(ioext.LimitReader(resp.Body, maxMemory))
110-
err := fmt.Errorf("invalid response status code: %d body: %s", resp.StatusCode, string(b))
111-
return resultext.Err[T, error](err)
116+
return resultext.Err[T, error](ErrUnexpectedResponse{Response: resp})
112117
}
113118

114119
data, err := DecodeResponse[T](resp, maxMemory)

0 commit comments

Comments
 (0)