Created
December 13, 2018 21:44
-
-
Save Solution/6570643918ef5753809bc8e7783855e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package client | |
import ( | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"github.com/Solution/go-httpwares" | |
"github.com/Solution/go-httpwares/metrics" | |
"github.com/Solution/go-httpwares/tags" | |
"net/http" | |
"time" | |
) | |
type Client struct { | |
MaxRetries int | |
HttpClient *http.Client | |
RequestFactory *RequestFactory | |
} | |
func (c *Client) SetMaxRetries(retries int) { | |
c.MaxRetries = retries | |
} | |
func (c *Client) PrepareRequest(method Method, path string, options map[string]string, body string) (*http.Request) { | |
return c.RequestFactory.Create(method, path, options, body) | |
} | |
func (c *Client) DoRequest(request *http.Request, retries int) (*http.Response, error) { | |
var ( | |
response *http.Response | |
err error | |
preprocessedResponseStatus error | |
i int | |
) | |
retryLoop: | |
for i = 1; i <= retries; i++ { | |
// request the client | |
response, err = c.HttpClient.Do(request) | |
// probably some network err, skip any other resolving | |
if response == nil { | |
break retryLoop | |
} | |
preprocessedResponseStatus = c.preprocessResponse(response, err) | |
if preprocessedResponseStatus == nil { | |
break retryLoop | |
} | |
switch preprocessedResponseStatus.(type) { | |
case HttpAuthorizationRequired, HttpRequestError, HttpDuplicateError: | |
break retryLoop | |
default: | |
} | |
time.Sleep(time.Duration(DefaultRetrySleep.Nanoseconds() * int64(i))) | |
} | |
if response == nil && err != nil { | |
return nil, NewUnableToProcessRequest( | |
"Unable to process request, probably due to network error", | |
err, | |
0, | |
) | |
} | |
return response, preprocessedResponseStatus | |
} | |
func (c *Client) preprocessResponse(response *http.Response, err error) error { | |
if SuccessfulCodes[response.StatusCode] { | |
return nil | |
} | |
byteBody, _ := ioutil.ReadAll(response.Body) | |
defer response.Body.Close() | |
if HttpCode(response.StatusCode) == Duplicate { | |
return NewHttpDuplicateError( | |
fmt.Sprintf("Resource already exists: %s", string(byteBody)), | |
err, | |
response.StatusCode, | |
) | |
} | |
if response.StatusCode >= 500 { | |
return NewHttpApplicationError( | |
fmt.Sprintf("Application error occured: %s", string(byteBody)), | |
err, | |
response.StatusCode, | |
) | |
} | |
if UnauthorizedCodes[response.StatusCode] { | |
return NewHttpAuthorizationRequired( | |
fmt.Sprintf("Unauthorized client: %s", string(byteBody)), | |
err, | |
response.StatusCode, | |
) | |
} | |
return NewHttpRequestError( | |
fmt.Sprintf("Client request error: %s", string(byteBody)), | |
err, | |
response.StatusCode, | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment