diff --git a/actor/v7action/curl.go b/actor/v7action/curl.go index cd38802510..caa60f3cd8 100644 --- a/actor/v7action/curl.go +++ b/actor/v7action/curl.go @@ -47,8 +47,19 @@ func (actor Actor) MakeCurlRequest( requestBodyBytes, ) - if err != nil && failOnHTTPError { - return nil, nil, translatableerror.CurlExit22Error{StatusCode: httpResponse.StatusCode} + if err != nil { + // A nil HTTP response means the request never reached the API (e.g. a token + // refresh or other authentication failure in the request wrapper). There is no + // status code to read and no response body to print, so surface the error + // directly. This also avoids a nil-pointer dereference on httpResponse below + // when the fail-on-http-error flag is set. + if httpResponse == nil { + return nil, nil, err + } + + if failOnHTTPError { + return nil, nil, translatableerror.CurlExit22Error{StatusCode: httpResponse.StatusCode} + } } return responseBody, httpResponse, nil diff --git a/actor/v7action/curl_test.go b/actor/v7action/curl_test.go index 4f6120b425..fce810dfc2 100644 --- a/actor/v7action/curl_test.go +++ b/actor/v7action/curl_test.go @@ -247,5 +247,33 @@ var _ = Describe("Curl Actions", func() { }) }) }) + + When("the request fails before an HTTP response is received", func() { + // e.g. a token refresh / authentication failure in the request wrapper, where + // no request reaches the API and there is no HTTP response. + BeforeEach(func() { + mockErr = errors.New("Bad credentials") + mockResponseBody = nil + mockHTTPResponse = nil + }) + + It("surfaces the error instead of returning empty output", func() { + Expect(executeErr).To(MatchError("Bad credentials")) + Expect(responseBody).To(BeNil()) + Expect(httpResponse).To(BeNil()) + }) + + When("the fail-on-http-errors flag is set", func() { + BeforeEach(func() { + failOnHTTPError = true + }) + + It("surfaces the error without panicking on the nil response", func() { + Expect(executeErr).To(MatchError("Bad credentials")) + Expect(responseBody).To(BeNil()) + Expect(httpResponse).To(BeNil()) + }) + }) + }) }) })