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 }