Skip to content

Commit 21970a8

Browse files
committed
1 parent 781229e commit 21970a8

File tree

2 files changed

+41
-60
lines changed

2 files changed

+41
-60
lines changed

AGENT.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Anka Cloud Gitlab Executor Agent Guidelines
2+
3+
1. Keep code D.R.Y (Don't Repeat Yourself) to avoid code duplication and improve readability.
4+
2. Use meaningful variable names that can be read by a human easily.
5+
3. Prioritize adding logs and having the developer run the code locally to debug issues if you don't know the answer.

internal/ankacloud/client.go

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,30 @@ func (c *APIClient) parse(body []byte) (response, error) {
4040
return r, nil
4141
}
4242

43+
// readResponseBodyWithRetry reads the response body and retries once on unexpected EOF
44+
func (c *APIClient) readResponseBodyWithRetry(resp *http.Response, req *http.Request) ([]byte, *http.Response, error) {
45+
bodyBytes, err := io.ReadAll(resp.Body)
46+
if err != nil {
47+
if strings.Contains(err.Error(), "unexpected EOF") {
48+
time.Sleep(5 * time.Second)
49+
// Retry once on unexpected EOF
50+
retryResp, retryErr := c.HttpClient.Do(req)
51+
if retryErr != nil {
52+
return nil, nil, retryErr
53+
}
54+
defer retryResp.Body.Close()
55+
56+
bodyBytes, retryErr = io.ReadAll(retryResp.Body)
57+
if retryErr != nil {
58+
return nil, nil, fmt.Errorf("failed to read response body (retry): %w", retryErr)
59+
}
60+
return bodyBytes, retryResp, nil
61+
}
62+
return nil, nil, fmt.Errorf("failed to read response body: %w", err)
63+
}
64+
return bodyBytes, resp, nil
65+
}
66+
4367
func toQueryParams(params map[string]string) url.Values {
4468
query := url.Values{}
4569
for k, v := range params {
@@ -76,28 +100,12 @@ func (c *APIClient) Post(ctx context.Context, endpoint string, payload interface
76100
}
77101
defer r.Body.Close()
78102

79-
bodyBytes, err := io.ReadAll(r.Body)
103+
bodyBytes, r, err := c.readResponseBodyWithRetry(r, req)
80104
if err != nil {
81-
if strings.Contains(err.Error(), "unexpected EOF") {
82-
time.Sleep(5 * time.Second)
83-
// Retry once on unexpected EOF
84-
r2, err2 := c.HttpClient.Do(req)
85-
if err2 != nil {
86-
if e, ok := err2.(*url.Error); ok && e.Timeout() {
87-
return nil, gitlab.TransientError(fmt.Errorf("failed to send POST request to %s with payload %+v (retry): %w", endpointUrl, payload, e))
88-
}
89-
return nil, fmt.Errorf("failed to send POST request to %s with payload %+v (retry): %w", endpoint, payload, err2)
90-
}
91-
defer r2.Body.Close()
92-
93-
bodyBytes, err2 = io.ReadAll(r2.Body)
94-
if err2 != nil {
95-
return nil, fmt.Errorf("failed to read response body (retry): %w", err2)
96-
}
97-
r = r2
98-
} else {
99-
return nil, fmt.Errorf("failed to read response body: %w", err)
105+
if e, ok := err.(*url.Error); ok && e.Timeout() {
106+
return nil, gitlab.TransientError(fmt.Errorf("failed to send POST request to %s with payload %+v (retry): %w", endpointUrl, payload, e))
100107
}
108+
return nil, err
101109
}
102110

103111
baseResponse, err := c.parse(bodyBytes)
@@ -141,28 +149,12 @@ func (c *APIClient) Delete(ctx context.Context, endpoint string, payload interfa
141149
}
142150
defer r.Body.Close()
143151

144-
bodyBytes, err := io.ReadAll(r.Body)
152+
bodyBytes, r, err := c.readResponseBodyWithRetry(r, req)
145153
if err != nil {
146-
if strings.Contains(err.Error(), "unexpected EOF") {
147-
time.Sleep(5 * time.Second)
148-
// Retry once on unexpected EOF
149-
r2, err2 := c.HttpClient.Do(req)
150-
if err2 != nil {
151-
if e, ok := err2.(*url.Error); ok && e.Timeout() {
152-
return nil, gitlab.TransientError(fmt.Errorf("failed to send DELETE request to %s with payload %+v (retry): %w", endpointUrl, payload, e))
153-
}
154-
return nil, fmt.Errorf("failed to send DELETE request to %s with payload %+v (retry): %w", endpoint, payload, err2)
155-
}
156-
defer r2.Body.Close()
157-
158-
bodyBytes, err2 = io.ReadAll(r2.Body)
159-
if err2 != nil {
160-
return nil, fmt.Errorf("failed to read response body (retry): %w", err2)
161-
}
162-
r = r2
163-
} else {
164-
return nil, fmt.Errorf("failed to read response body: %w", err)
154+
if e, ok := err.(*url.Error); ok && e.Timeout() {
155+
return nil, gitlab.TransientError(fmt.Errorf("failed to send DELETE request to %s with payload %+v (retry): %w", endpointUrl, payload, e))
165156
}
157+
return nil, err
166158
}
167159

168160
baseResponse, err := c.parse(bodyBytes)
@@ -203,28 +195,12 @@ func (c *APIClient) Get(ctx context.Context, endpoint string, queryParams map[st
203195
}
204196
defer r.Body.Close()
205197

206-
bodyBytes, err := io.ReadAll(r.Body)
198+
bodyBytes, r, err := c.readResponseBodyWithRetry(r, req)
207199
if err != nil {
208-
if strings.Contains(err.Error(), "unexpected EOF") {
209-
time.Sleep(5 * time.Second)
210-
// Retry once on unexpected EOF
211-
r2, err2 := c.HttpClient.Do(req)
212-
if err2 != nil {
213-
if e, ok := err2.(*url.Error); ok && e.Timeout() {
214-
return nil, gitlab.TransientError(fmt.Errorf("failed to send GET request to %s (retry): %w", endpointUrl, e))
215-
}
216-
return nil, fmt.Errorf("failed to send GET request to %s (retry): %w", endpointUrl, err2)
217-
}
218-
defer r2.Body.Close()
219-
220-
bodyBytes, err2 = io.ReadAll(r2.Body)
221-
if err2 != nil {
222-
return nil, fmt.Errorf("failed to read response body (retry): %w", err2)
223-
}
224-
r = r2
225-
} else {
226-
return nil, fmt.Errorf("failed to read response body: %w", err)
200+
if e, ok := err.(*url.Error); ok && e.Timeout() {
201+
return nil, gitlab.TransientError(fmt.Errorf("failed to send GET request to %s (retry): %w", endpointUrl, e))
227202
}
203+
return nil, err
228204
}
229205

230206
baseResponse, err := c.parse(bodyBytes)

0 commit comments

Comments
 (0)