Skip to content

Commit e569bcf

Browse files
committed
Fix(curl): surface auth errors and avoid panic on nil HTTP response
MakeCurlRequest assumed that a non-nil error always came with an HTTP response (e.g. a 4xx/5xx from the API). That assumption breaks when the request fails before reaching the API — for example a token refresh / client-credentials authentication failure in the UAA request wrapper, which returns an error with a nil *http.Response. In that case: - Without --fail, the error was swallowed and cf curl printed empty output, giving the user no indication anything went wrong. - With --fail, the code dereferenced httpResponse.StatusCode on the nil response and panicked. Only surface CurlExit22Error when an HTTP response is actually present; when the response is nil, return the underlying error directly so the user sees a real message (e.g. "Bad credentials") and cf curl exits cleanly instead of panicking. Existing behavior for real HTTP error responses (print body by default, fail only with --fail) is unchanged. Also, sync .grype.yaml exclusions with main so check-cves ignores test fixtures Signed-off-by: Prem Kumar Kalle <prem.kalle@broadcom.com>
1 parent 5883401 commit e569bcf

5 files changed

Lines changed: 68 additions & 29 deletions

File tree

.grype.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
ignore:
2-
- package:
3-
type: gem
1+
exclude:
2+
- './integration/assets'
3+
- './fixtures/applications'

actor/v7action/curl.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,19 @@ func (actor Actor) MakeCurlRequest(
4747
requestBodyBytes,
4848
)
4949

50-
if err != nil && failOnHTTPError {
51-
return nil, nil, translatableerror.CurlExit22Error{StatusCode: httpResponse.StatusCode}
50+
if err != nil {
51+
// A nil HTTP response means the request never reached the API (e.g. a token
52+
// refresh or other authentication failure in the request wrapper). There is no
53+
// status code to read and no response body to print, so surface the error
54+
// directly. This also avoids a nil-pointer dereference on httpResponse below
55+
// when the fail-on-http-error flag is set.
56+
if httpResponse == nil {
57+
return nil, nil, err
58+
}
59+
60+
if failOnHTTPError {
61+
return nil, nil, translatableerror.CurlExit22Error{StatusCode: httpResponse.StatusCode}
62+
}
5263
}
5364

5465
return responseBody, httpResponse, nil

actor/v7action/curl_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,5 +247,33 @@ var _ = Describe("Curl Actions", func() {
247247
})
248248
})
249249
})
250+
251+
When("the request fails before an HTTP response is received", func() {
252+
// e.g. a token refresh / authentication failure in the request wrapper, where
253+
// no request reaches the API and there is no HTTP response.
254+
BeforeEach(func() {
255+
mockErr = errors.New("Bad credentials")
256+
mockResponseBody = nil
257+
mockHTTPResponse = nil
258+
})
259+
260+
It("surfaces the error instead of returning empty output", func() {
261+
Expect(executeErr).To(MatchError("Bad credentials"))
262+
Expect(responseBody).To(BeNil())
263+
Expect(httpResponse).To(BeNil())
264+
})
265+
266+
When("the fail-on-http-errors flag is set", func() {
267+
BeforeEach(func() {
268+
failOnHTTPError = true
269+
})
270+
271+
It("surfaces the error without panicking on the nil response", func() {
272+
Expect(executeErr).To(MatchError("Bad credentials"))
273+
Expect(responseBody).To(BeNil())
274+
Expect(httpResponse).To(BeNil())
275+
})
276+
})
277+
})
250278
})
251279
})

go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ require (
7777
github.com/openzipkin/zipkin-go v0.4.3 // indirect
7878
github.com/spf13/pflag v1.0.9 // indirect
7979
github.com/x448/float16 v0.8.4 // indirect
80-
go.opentelemetry.io/otel v1.43.0 // indirect
81-
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
80+
go.opentelemetry.io/otel v1.45.0 // indirect
81+
go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect
8282
go.yaml.in/yaml/v2 v2.4.3 // indirect
8383
go.yaml.in/yaml/v3 v3.0.5 // indirect
8484
golang.org/x/mod v0.38.0 // indirect
85-
golang.org/x/oauth2 v0.34.0 // indirect
85+
golang.org/x/oauth2 v0.36.0 // indirect
8686
golang.org/x/sync v0.22.0 // indirect
8787
golang.org/x/sys v0.47.0 // indirect
8888
golang.org/x/time v0.14.0 // indirect
8989
golang.org/x/tools v0.48.0 // indirect
90-
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 // indirect
91-
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
92-
google.golang.org/grpc v1.80.0 // indirect
90+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
91+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
92+
google.golang.org/grpc v1.82.1 // indirect
9393
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
9494
gopkg.in/inf.v0 v0.9.1 // indirect
9595
k8s.io/klog/v2 v2.140.0 // indirect

go.sum

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -277,16 +277,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
277277
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
278278
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
279279
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
280-
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
281-
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
282-
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
283-
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
284-
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
285-
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
286-
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
287-
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
288-
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
289-
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
280+
go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
281+
go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
282+
go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
283+
go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
284+
go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
285+
go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
286+
go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
287+
go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
288+
go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
289+
go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
290290
go.step.sm/crypto v0.85.0 h1:h3U9gzCcxP1fWbseqy+CwsTxzHFNuoblefy7YP4jBHk=
291291
go.step.sm/crypto v0.85.0/go.mod h1:Rp/BdP0/ZJ7eYREhXcE4izCABLp0e8ziFqb0LBNG7Cc=
292292
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
@@ -322,8 +322,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
322322
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
323323
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
324324
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
325-
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
326-
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
325+
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
326+
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
327327
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
328328
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
329329
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -382,12 +382,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
382382
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
383383
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
384384
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
385-
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM=
386-
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw=
387-
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
388-
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
389-
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
390-
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
385+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
386+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
387+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
388+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
389+
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
390+
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
391391
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
392392
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
393393
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

0 commit comments

Comments
 (0)