Skip to content

Commit 1f321ab

Browse files
authored
Feat context cancel (#7)
* update deps + tools * update * adding watch * fixing tests * adding * adding tests, fixing format * adding more tests to options * small lint fixes * adding documentation * adding ability to cancel API calls * adding docs * removing lint * adding fix * fixing go ver * fixing dependabot
1 parent f25ca18 commit 1f321ab

17 files changed

Lines changed: 574 additions & 368 deletions

.covignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.gen.go
2+
dad_jokes.go

.github/dependabot.yaml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ updates:
55
directory: /
66
schedule:
77
interval: monthly
8-
- directory: github
9-
package-ecosystem: github-actions
8+
groups:
9+
prod:
10+
patterns:
11+
- "*"
12+
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
1015
schedule:
11-
interval: monthly
16+
interval: "monthly"
17+
groups:
18+
prod:
19+
patterns:
20+
- "*"

.github/workflows/pull-request.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ on:
99
types: [opened, synchronize, reopened]
1010

1111

12-
env:
13-
GOLANG_VERSION: 1.22
1412

1513
jobs:
1614

@@ -36,9 +34,10 @@ jobs:
3634
fetch-depth: 0
3735

3836
- name: Setup golang ${{ env.GOLANG_VERSION }}
39-
uses: actions/setup-go@v4
37+
uses: actions/setup-go@v6
4038
with:
41-
go-version: ${{ env.GOLANG_VERSION }}
39+
go-version-file: go.mod
40+
cache-dependency-path: go.sum
4241

4342
- name: install tools
4443
run: make install-ci

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
.DS_Store
3+
coverage*

.golangci.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
version: "2"
2+
3+
linters:
4+
enable:
5+
- cyclop
6+
- nestif
7+
- bodyclose
8+
- iface
9+
- gosec
10+
- errcheck
11+
- errchkjson
12+
- errname
13+
- errorlint
14+
- exptostd
15+
- fatcontext
16+
- forbidigo
17+
- forcetypeassert
18+
- govet
19+
- importas
20+
- ireturn
21+
- perfsprint
22+
- recvcheck
23+
- sloglint
24+
- staticcheck
25+
- unparam
26+
- unused
27+
- wastedassign
28+
exclusions:
29+
generated: lax
30+
31+
rules:
32+
# Exclude some linters from running on tests files.
33+
- path: _test\.go
34+
35+
linters:
36+
- gocyclo
37+
- cyclop
38+
- dupl
39+
- gosec
40+
- forbidigo
41+
- bodyclose
42+
- exhaustruct
43+
- fatcontext
44+
45+
- path: dad_jokes.go
46+
linters:
47+
- forbidigo
48+
- errchkjson
49+
50+
settings:
51+
depguard:
52+
rules:
53+
main:
54+
list-mode: lax
55+
56+

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,28 @@ if err != nil {
9797

9898
```
9999

100+
101+
### Cancelable HTTP calls
102+
Use <method>Ctx if you want more granular control and the ability to cancel.
103+
104+
```go
105+
var apiErr *fetch.APIError
106+
ctx, cancel := context.WithCancel(context.Background())
107+
defer cancel()
108+
109+
resp, err := client.PutCtx(ctx,url, bytes.NewReader([]byte(`{"hello": "world"}`)), nil)
110+
if err != nil {
111+
if errors.is(err, context.Canceled) {
112+
// Handle context cancelled
113+
}
114+
if errors.As(err, &apiErr) {
115+
fmt.Println("API Response error", apiErr)
116+
}
117+
// Handle non-API Error
118+
}
119+
```
120+
121+
100122
<br>
101123
<br>
102124

errors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type APIError struct {
1616
}
1717

1818
func (e *APIError) Error() string {
19-
return fmt.Sprintf("%s [%d]: %s", e.StatusText, e.StatusCode, e.Message)
19+
return fmt.Sprintf("%s: [%d]: %s", e.StatusText, e.StatusCode, e.Message)
2020
}
2121

2222
func (e *APIError) Unwrap() error {

errors_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestAPIError_Error(t *testing.T) {
2626
StatusText: http.StatusText(http.StatusBadRequest),
2727
Message: "there was an issue with the request",
2828
},
29-
want: "Bad Request [400]: there was an issue with the request",
29+
want: "Bad Request: [400]: there was an issue with the request",
3030
},
3131
{
3232
name: "should return 5xx error",
@@ -35,7 +35,7 @@ func TestAPIError_Error(t *testing.T) {
3535
StatusText: http.StatusText(http.StatusInternalServerError),
3636
Message: "there was an issue with the request",
3737
},
38-
want: "Internal Server Error [500]: there was an issue with the request",
38+
want: "Internal Server Error: [500]: there was an issue with the request",
3939
},
4040
}
4141
for _, tt := range tests {
@@ -79,3 +79,18 @@ func TestAPIError_errors_is(t *testing.T) {
7979
err := fn()
8080
odize.AssertEqual(t, err.Error(), expected.Error())
8181
}
82+
83+
func TestAPIError_Unwrap(t *testing.T) {
84+
var err *APIError
85+
expectedErr := APIError{
86+
StatusCode: http.StatusBadRequest,
87+
StatusText: http.StatusText(http.StatusBadRequest),
88+
Message: "some issue",
89+
}
90+
var testErr error = &expectedErr
91+
if errors.As(testErr, &err) {
92+
odize.AssertEqual(t, err.Unwrap().Error(), expectedErr.Error())
93+
} else {
94+
t.Error("non matching error")
95+
}
96+
}

0 commit comments

Comments
 (0)