github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/http/error_transport.go (about)

     1  /*
     2   * Copyright 2020 The Compass Authors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package http
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"net/http"
    23  
    24  	"github.com/kyma-incubator/compass/components/director/pkg/log"
    25  	"github.com/pkg/errors"
    26  )
    27  
    28  // NewErrorHandlerTransport missing godoc
    29  func NewErrorHandlerTransport(roundTripper HTTPRoundTripper) *ErrorHandlerTransport {
    30  	return &ErrorHandlerTransport{
    31  		roundTripper: roundTripper,
    32  	}
    33  }
    34  
    35  // ErrorHandlerTransport missing godoc
    36  type ErrorHandlerTransport struct {
    37  	roundTripper HTTPRoundTripper
    38  }
    39  
    40  // RoundTrip missing godoc
    41  func (c *ErrorHandlerTransport) RoundTrip(request *http.Request) (*http.Response, error) {
    42  	response, err := c.roundTripper.RoundTrip(request)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	if response.StatusCode >= http.StatusBadRequest {
    48  		return nil, handleResponseError(request.Context(), response)
    49  	}
    50  
    51  	return response, nil
    52  }
    53  
    54  // Clone clones the underlying transport.
    55  func (c *ErrorHandlerTransport) Clone() HTTPRoundTripper {
    56  	return &ErrorHandlerTransport{
    57  		roundTripper: c.roundTripper.Clone(),
    58  	}
    59  }
    60  
    61  // GetTransport returns the underlying transport.
    62  func (c *ErrorHandlerTransport) GetTransport() *http.Transport {
    63  	return c.roundTripper.GetTransport()
    64  }
    65  
    66  func handleResponseError(ctx context.Context, response *http.Response) error {
    67  	defer func() {
    68  		if err := response.Body.Close(); err != nil {
    69  			log.C(ctx).Errorf("ReadCloser couldn't be closed: %v", err)
    70  		}
    71  	}()
    72  
    73  	body, err := io.ReadAll(response.Body)
    74  	if err != nil {
    75  		return errors.Wrap(err, "while reading response body bytes")
    76  	}
    77  
    78  	err = errors.Errorf("statusCode: %d Body: %s", response.StatusCode, body)
    79  	if response.Request != nil {
    80  		return errors.WithMessagef(err, "%s %s", response.Request.Method, response.Request.URL)
    81  	}
    82  
    83  	return errors.WithMessagef(err, "request failed")
    84  }