@@ -21,6 +21,7 @@ import (
21
21
"context"
22
22
"encoding/json"
23
23
"errors"
24
+ "fmt"
24
25
"io"
25
26
"math"
26
27
"net/http"
@@ -106,12 +107,12 @@ func (s *SnykCodeHTTPClient) GetFilters(ctx context.Context) (
106
107
span := s .instrumentor .StartSpan (ctx , method )
107
108
defer s .instrumentor .Finish (span )
108
109
109
- responseBody , err := s .doCall (span .Context (), "GET" , "/filters" , nil )
110
+ body , _ , err := s .doCall (span .Context (), "GET" , "/filters" , nil )
110
111
if err != nil {
111
112
return FiltersResponse {ConfigFiles : nil , Extensions : nil }, err
112
113
}
113
114
114
- err = json .Unmarshal (responseBody , & filters )
115
+ err = json .Unmarshal (body , & filters )
115
116
if err != nil {
116
117
return FiltersResponse {ConfigFiles : nil , Extensions : nil }, err
117
118
}
@@ -134,53 +135,50 @@ func (s *SnykCodeHTTPClient) CreateBundle(
134
135
return "" , nil , err
135
136
}
136
137
137
- responseBody , err := s .doCall (span .Context (), "POST" , "/bundle" , requestBody )
138
+ body , _ , err := s .doCall (span .Context (), "POST" , "/bundle" , requestBody )
138
139
if err != nil {
139
140
return "" , nil , err
140
141
}
141
142
142
143
var bundle bundleResponse
143
- err = json .Unmarshal (responseBody , & bundle )
144
+ err = json .Unmarshal (body , & bundle )
144
145
if err != nil {
145
146
return "" , nil , err
146
147
}
147
148
s .c .Logger ().Debug ().Str ("method" , method ).Msg ("API: Create done" )
148
149
return bundle .BundleHash , bundle .MissingFiles , nil
149
150
}
150
151
151
- func (s * SnykCodeHTTPClient ) doCall (ctx context.Context ,
152
- method string ,
153
- path string ,
154
- requestBody []byte ,
155
- ) (responseBody []byte , _ error ) {
152
+ func (s * SnykCodeHTTPClient ) doCall (ctx context.Context , method string , path string , requestBody []byte ) ([]byte , int , error ) {
156
153
span := s .instrumentor .StartSpan (ctx , "code.doCall" )
157
154
defer s .instrumentor .Finish (span )
158
155
159
156
const retryCount = 3
157
+
158
+ // we only retry, if we get a retryable http status code
160
159
for i := 0 ; i < retryCount ; i ++ {
161
160
requestId , err := performance2 .GetTraceId (span .Context ())
162
161
if err != nil {
163
- return nil , errors .New ("Code request id was not provided. " + err .Error ())
162
+ return nil , 0 , errors .New ("Code request id was not provided. " + err .Error ())
164
163
}
165
164
166
165
bodyBuffer , err := s .encodeIfNeeded (method , requestBody )
167
166
if err != nil {
168
- return nil , err
167
+ return nil , 0 , err
169
168
}
170
169
171
170
c := config .CurrentConfig ()
172
171
req , err := s .newRequest (c , method , path , bodyBuffer , requestId )
173
172
if err != nil {
174
- return nil , err
173
+ return nil , 0 , err
175
174
}
176
175
177
176
s .c .Logger ().Trace ().Str ("requestBody" , string (requestBody )).Str ("snyk-request-id" , requestId ).Msg ("SEND TO REMOTE" )
178
177
179
- response , body , err := s .httpCall (req ) //nolint:bodyclose // false positive
180
- responseBody = body
178
+ responseBody , httpStatusCode , err := s .httpCall (req )
181
179
182
- if response != nil && responseBody != nil {
183
- s .c .Logger ().Trace ().Str ("response.Status" , response . Status ).
180
+ if responseBody != nil {
181
+ s .c .Logger ().Trace ().Int ("response.Status" , httpStatusCode ).
184
182
Str ("responseBody" , string (responseBody )).
185
183
Str ("snyk-request-id" , requestId ).
186
184
Msg ("RECEIVED FROM REMOTE" )
@@ -191,51 +189,58 @@ func (s *SnykCodeHTTPClient) doCall(ctx context.Context,
191
189
}
192
190
193
191
if err != nil {
194
- return nil , err // no retries for errors
192
+ return nil , 0 , err // no retries for errors
195
193
}
196
194
197
- err = s .checkResponseCode (response )
195
+ err = s .checkResponseCode (httpStatusCode )
198
196
if err != nil {
199
- if retryErrorCodes [response . StatusCode ] {
197
+ if retryErrorCodes [httpStatusCode ] {
200
198
s .c .Logger ().Debug ().Err (err ).Str ("method" , method ).Int ("attempts done" , i + 1 ).Msgf ("retrying" )
201
199
if i < retryCount - 1 {
202
200
time .Sleep (5 * time .Second )
203
201
continue
204
202
}
205
203
// return the error on last try
206
- return nil , err
204
+ return nil , httpStatusCode , err
207
205
}
208
- return nil , err
206
+ return nil , httpStatusCode , err
209
207
}
210
208
// no error, we can break the retry loop
211
- break
209
+ return responseBody , httpStatusCode , nil
212
210
}
213
- return responseBody , nil
211
+ return nil , 0 , nil
214
212
}
215
213
216
- func (s * SnykCodeHTTPClient ) httpCall (req * http.Request ) (* http. Response , []byte , error ) {
214
+ func (s * SnykCodeHTTPClient ) httpCall (req * http.Request ) ([]byte , int , error ) {
217
215
method := "code.httpCall"
216
+ logger := s .c .Logger ().With ().Str ("method" , method ).Logger ()
217
+ statusCode := 0
218
+
218
219
response , err := s .client ().Do (req )
219
220
if err != nil {
220
- s .c .Logger ().Err (err ).Str ("method" , method ).Msgf ("got http error" )
221
- s .errorReporter .CaptureError (err , codeClientObservability.ErrorReporterOptions {ErrorDiagnosticPath : req .RequestURI })
222
- return nil , nil , err
221
+ logger .Err (err ).Msgf ("got http error" )
222
+ return nil , statusCode , err
223
+ }
224
+
225
+ if response == nil {
226
+ return nil , 0 , nil
223
227
}
224
228
225
229
defer func () {
226
- closeErr := response .Body .Close ()
227
- if closeErr != nil {
228
- s . c . Logger (). Err (closeErr ).Msg ("Couldn't close response body in call to Snyk Code " )
230
+ bodyCloseErr := response .Body .Close ()
231
+ if bodyCloseErr != nil {
232
+ logger . Err (bodyCloseErr ).Msg ("failed to close response body" )
229
233
}
230
234
}()
231
- responseBody , err := io .ReadAll (response .Body )
232
235
233
- if err != nil {
234
- s .c .Logger ().Err (err ).Str ("method" , method ).Msgf ("error reading response body" )
235
- s .errorReporter .CaptureError (err , codeClientObservability.ErrorReporterOptions {ErrorDiagnosticPath : req .RequestURI })
236
- return nil , nil , err
236
+ statusCode = response .StatusCode
237
+ responseBody , readErr := io .ReadAll (response .Body )
238
+
239
+ if readErr != nil {
240
+ logger .Err (readErr ).Msg ("failed to read response body" )
241
+ return responseBody , statusCode , err
237
242
}
238
- return response , responseBody , nil
243
+ return responseBody , statusCode , nil
239
244
}
240
245
241
246
func (s * SnykCodeHTTPClient ) newRequest (
@@ -313,11 +318,16 @@ func (s *SnykCodeHTTPClient) ExtendBundle(
313
318
removedFiles []string ,
314
319
) (string , []string , error ) {
315
320
method := "code.ExtendBundle"
316
- s .c .Logger ().Debug ().Str ("method" , method ).Msg ("API: Extending bundle for " + strconv .Itoa (len (files )) + " files" )
317
- defer s .c .Logger ().Debug ().Str ("method" , method ).Msg ("API: Extend done" )
318
-
319
321
span := s .instrumentor .StartSpan (ctx , method )
320
322
defer s .instrumentor .Finish (span )
323
+ requestId , err := performance2 .GetTraceId (span .Context ())
324
+ logger := s .c .Logger ().With ().Str ("method" , method ).Str ("requestId" , requestId ).Logger ()
325
+ if err != nil {
326
+ logger .Err (err ).Msg ("failed to get request id" )
327
+ }
328
+
329
+ logger .Debug ().Msg ("API: Extending bundle for " + strconv .Itoa (len (files )) + " files" )
330
+ defer logger .Debug ().Msg ("API: Extend done" )
321
331
322
332
requestBody , err := json .Marshal (extendBundleRequest {
323
333
Files : files ,
@@ -327,7 +337,12 @@ func (s *SnykCodeHTTPClient) ExtendBundle(
327
337
return "" , nil , err
328
338
}
329
339
330
- responseBody , err := s .doCall (span .Context (), "PUT" , "/bundle/" + bundleHash , requestBody )
340
+ responseBody , httpStatus , err := s .doCall (span .Context (), "PUT" , "/bundle/" + bundleHash , requestBody )
341
+ if httpStatus == http .StatusBadRequest {
342
+ logger .Err (err ).Msg ("got an HTTP 400 Bad Request, dumping bundle infos for analysis" )
343
+ logger .Error ().Any ("fileHashes" , files ).Send ()
344
+ logger .Error ().Any ("removedFiles" , removedFiles ).Send ()
345
+ }
331
346
if err != nil {
332
347
return "" , nil , err
333
348
}
@@ -364,7 +379,7 @@ func (s *SnykCodeHTTPClient) RunAnalysis(
364
379
return nil , AnalysisStatus {}, err
365
380
}
366
381
367
- responseBody , err := s .doCall (span .Context (), "POST" , "/analysis" , requestBody )
382
+ responseBody , _ , err := s .doCall (span .Context (), "POST" , "/analysis" , requestBody )
368
383
failed := AnalysisStatus {message : "FAILED" }
369
384
if err != nil {
370
385
s .c .Logger ().Err (err ).Str ("method" , method ).Str ("responseBody" , string (responseBody )).Msg ("error response from analysis" )
@@ -434,11 +449,11 @@ func (s *SnykCodeHTTPClient) analysisRequestBody(options *AnalysisOptions) ([]by
434
449
return requestBody , err
435
450
}
436
451
437
- func (s * SnykCodeHTTPClient ) checkResponseCode (r * http. Response ) error {
438
- if r . StatusCode >= 200 && r . StatusCode <= 299 {
452
+ func (s * SnykCodeHTTPClient ) checkResponseCode (statusCode int ) error {
453
+ if statusCode >= 200 && statusCode <= 400 {
439
454
return nil
440
455
}
441
- return errors . New ("Unexpected response code: " + r . Status )
456
+ return fmt . Errorf ("Unexpected response code: %d" , statusCode )
442
457
}
443
458
444
459
type AutofixStatus struct {
@@ -508,7 +523,7 @@ func (s *SnykCodeHTTPClient) RunAutofix(ctx context.Context, options AutofixOpti
508
523
return AutofixResponse {}, err
509
524
}
510
525
511
- responseBody , err := s .doCall (span .Context (), "POST" , "/autofix/suggestions" , requestBody )
526
+ responseBody , _ , err := s .doCall (span .Context (), "POST" , "/autofix/suggestions" , requestBody )
512
527
513
528
if err != nil {
514
529
logger .Err (err ).Str ("responseBody" , string (responseBody )).Msg ("error response from autofix" )
@@ -578,7 +593,7 @@ func (s *SnykCodeHTTPClient) SubmitAutofixFeedback(ctx context.Context, fixId st
578
593
return err
579
594
}
580
595
581
- responseBody , err := s .doCall (span .Context (), "POST" , "/autofix/event" , requestBody )
596
+ responseBody , _ , err := s .doCall (span .Context (), "POST" , "/autofix/event" , requestBody )
582
597
if err != nil {
583
598
s .c .Logger ().Err (err ).Str ("method" , method ).Str ("responseBody" , string (responseBody )).Msg ("error response for autofix feedback" )
584
599
return err
0 commit comments