Skip to content

Instantly share code, notes, and snippets.

@Solution
Created December 13, 2018 21:44
Show Gist options
  • Save Solution/6570643918ef5753809bc8e7783855e9 to your computer and use it in GitHub Desktop.
Save Solution/6570643918ef5753809bc8e7783855e9 to your computer and use it in GitHub Desktop.
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