Verified Commit c093289e authored by Timo Furrer's avatar Timo Furrer 👶 Committed by GitLab
Browse files

feat: add StatusCode helper to extract HTTP status code from errors

Changelog: Improvements
parent a0286d44
Loading
Loading
Loading
Loading
+11 −0
Changes for gitlab.go: 11 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1490,6 +1490,17 @@ func HasStatusCode(err error, statusCode int) bool {
	return errResponse.HasStatusCode(statusCode)
}

// StatusCode returns the HTTP status code of the first *ErrorResponse
// in err's chain, or 0 if err does not wrap an *ErrorResponse.
func StatusCode(err error) int {
	errResponse, ok := errors.AsType[*ErrorResponse](err)
	if !ok {
		return 0
	}

	return errResponse.StatusCode
}

// newRetryableHTTPClientWithRetryCheck returns a `retryablehttp.Client` clone of itself with the given CheckRetry function
func (c *Client) newRetryableHTTPClientWithRetryCheck(cr retryablehttp.CheckRetry) *retryablehttp.Client {
	return &retryablehttp.Client{
+49 −0
Changes for gitlab_test.go: 49 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -881,6 +881,55 @@ func TestHasStatusCode(t *testing.T) {
	}
}

func TestStatusCode(t *testing.T) {
	t.Parallel()

	// GIVEN
	tests := []struct {
		name   string
		err    error
		expect int
	}{
		{
			name:   "error is nil",
			err:    nil,
			expect: 0,
		},
		{
			name:   "error is not a ErrorResponse",
			err:    errors.New("dummy"),
			expect: 0,
		},
		{
			name:   "error is a ErrorResponse without status code",
			err:    &ErrorResponse{},
			expect: 0,
		},
		{
			name:   "error is a ErrorResponse with status code",
			err:    &ErrorResponse{StatusCode: http.StatusServiceUnavailable, Response: &http.Response{StatusCode: http.StatusServiceUnavailable}},
			expect: http.StatusServiceUnavailable,
		},
		{
			name:   "error wraps a ErrorResponse",
			err:    fmt.Errorf("wrapped: %w", &ErrorResponse{StatusCode: http.StatusNotFound, Response: &http.Response{StatusCode: http.StatusNotFound}}),
			expect: http.StatusNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()

			// WHEN
			actual := StatusCode(tt.err)

			// THEN
			assert.Equal(t, tt.expect, actual)
		})
	}
}

func TestNewRequestToURL_disallowedURL(t *testing.T) {
	t.Parallel()