Skip to content

Commit 1619d27

Browse files
committed
verbose logging + retries for http calls that unexpected EOF
1 parent 5d127b9 commit 1619d27

File tree

3 files changed

+63
-8
lines changed

3 files changed

+63
-8
lines changed

internal/ankacloud/client.go

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"net/http"
1010
"net/url"
11+
"strings"
1112
"time"
1213

1314
"github.com/veertuinc/anka-cloud-gitlab-executor/internal/gitlab"
@@ -77,7 +78,25 @@ func (c *APIClient) Post(ctx context.Context, endpoint string, payload interface
7778

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

83102
baseResponse, err := c.parse(bodyBytes)
@@ -123,7 +142,25 @@ func (c *APIClient) Delete(ctx context.Context, endpoint string, payload interfa
123142

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

129166
baseResponse, err := c.parse(bodyBytes)
@@ -166,7 +203,25 @@ func (c *APIClient) Get(ctx context.Context, endpoint string, queryParams map[st
166203

167204
bodyBytes, err := io.ReadAll(r.Body)
168205
if err != nil {
169-
return nil, fmt.Errorf("failed to read response body: %w", err)
206+
if strings.Contains(err.Error(), "unexpected EOF") {
207+
// Retry once on unexpected EOF
208+
r2, err2 := c.HttpClient.Do(req)
209+
if err2 != nil {
210+
if e, ok := err2.(*url.Error); ok && e.Timeout() {
211+
return nil, gitlab.TransientError(fmt.Errorf("failed to send GET request to %s (retry): %w", endpointUrl, e))
212+
}
213+
return nil, fmt.Errorf("failed to send GET request to %s (retry): %w", endpointUrl, err2)
214+
}
215+
defer r2.Body.Close()
216+
217+
bodyBytes, err2 = io.ReadAll(r2.Body)
218+
if err2 != nil {
219+
return nil, fmt.Errorf("failed to read response body (retry): %w", err2)
220+
}
221+
r = r2
222+
} else {
223+
return nil, fmt.Errorf("failed to read response body: %w", err)
224+
}
170225
}
171226

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

internal/ankacloud/controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (c *controller) GetAllInstances(ctx context.Context) ([]Instance, error) {
176176

177177
body, err := c.APIClient.Get(ctx, "/api/v1/vm", nil)
178178
if err != nil {
179-
return nil, fmt.Errorf("failed to get instances: %w", err)
179+
return nil, fmt.Errorf("failed to get all instances: %w", err)
180180
}
181181

182182
var response getAllInstancesResponse
@@ -199,7 +199,7 @@ func (c *controller) GetInstanceByExternalId(ctx context.Context, externalId str
199199
return nil, fmt.Errorf("no instances returned from controller")
200200
}
201201
if err != nil {
202-
return nil, fmt.Errorf("failed to get instances: %w", err)
202+
return nil, fmt.Errorf("failed to get instance by external id %s: %w", externalId, err)
203203
}
204204

205205
for _, instance := range instances {

internal/command/cleanup.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func executeCleanup(ctx context.Context, env gitlab.Environment) error {
4646
log.Errorf("cleanup: failed to get instance by external id %q: %v", env.GitlabJobUrl, err)
4747
return fmt.Errorf("cleanup: failed to get instance by external id %q: %v", env.GitlabJobUrl, err)
4848
}
49-
log.Debugf("instance id: %s\n", instance.Id)
49+
log.Printf("instance id: %s\n", instance.Id)
5050

51-
log.Debugf("Issuing termination request for instance %s\n", instance.Id)
51+
log.Printf("Issuing termination request for instance %s\n", instance.Id)
5252
err = controller.TerminateInstance(ctx, ankacloud.TerminateInstanceRequest{
5353
Id: instance.Id,
5454
})
@@ -57,6 +57,6 @@ func executeCleanup(ctx context.Context, env gitlab.Environment) error {
5757
return fmt.Errorf("cleanup: failed to terminate instance %q: %v", instance.Id, err)
5858
}
5959

60-
log.Colorf("cleanup stage completed for job: %s", env.GitlabJobUrl)
60+
log.Println("cleanup stage completed for job: ", env.GitlabJobUrl)
6161
return nil
6262
}

0 commit comments

Comments
 (0)