HttpClient: Wrap errors with error classes

This commit is contained in:
Alex Crawford 2014-06-23 11:32:31 -07:00
parent 2c717a6cd1
commit 8496ffb53a

View File

@ -18,6 +18,20 @@ const (
HTTP_4xx = 4 HTTP_4xx = 4
) )
type Err error
type ErrTimeout struct{
Err
}
type ErrNotFound struct{
Err
}
type ErrInvalid struct{
Err
}
type HttpClient struct { type HttpClient struct {
// Maximum exp backoff duration. Defaults to 5 seconds // Maximum exp backoff duration. Defaults to 5 seconds
MaxBackoff time.Duration MaxBackoff time.Duration
@ -53,18 +67,18 @@ func expBackoff(interval, max time.Duration) time.Duration {
// Fetches a given URL with support for exponential backoff and maximum retries // Fetches a given URL with support for exponential backoff and maximum retries
func (h *HttpClient) Get(rawurl string) ([]byte, error) { func (h *HttpClient) Get(rawurl string) ([]byte, error) {
if rawurl == "" { if rawurl == "" {
return nil, errors.New("URL is empty. Skipping.") return nil, ErrInvalid{errors.New("URL is empty. Skipping.")}
} }
url, err := neturl.Parse(rawurl) url, err := neturl.Parse(rawurl)
if err != nil { if err != nil {
return nil, err return nil, ErrInvalid{err}
} }
// Unfortunately, url.Parse is too generic to throw errors if a URL does not // Unfortunately, url.Parse is too generic to throw errors if a URL does not
// have a valid HTTP scheme. So, we have to do this extra validation // have a valid HTTP scheme. So, we have to do this extra validation
if !strings.HasPrefix(url.Scheme, "http") { if !strings.HasPrefix(url.Scheme, "http") {
return nil, fmt.Errorf("URL %s does not have a valid HTTP scheme. Skipping.", rawurl) return nil, ErrInvalid{fmt.Errorf("URL %s does not have a valid HTTP scheme. Skipping.", rawurl)}
} }
dataURL := url.String() dataURL := url.String()
@ -106,7 +120,7 @@ func (h *HttpClient) Get(rawurl string) ([]byte, error) {
} }
if status == HTTP_4xx { if status == HTTP_4xx {
return nil, fmt.Errorf("Not found. HTTP status code: %d", resp.StatusCode) return nil, ErrNotFound{fmt.Errorf("Not found. HTTP status code: %d", resp.StatusCode)}
} }
log.Printf("Server error. HTTP status code: %d", resp.StatusCode) log.Printf("Server error. HTTP status code: %d", resp.StatusCode)
@ -119,5 +133,5 @@ func (h *HttpClient) Get(rawurl string) ([]byte, error) {
time.Sleep(duration) time.Sleep(duration)
} }
return nil, fmt.Errorf("Unable to fetch data. Maximum retries reached: %d", h.MaxRetries) return nil, ErrTimeout{fmt.Errorf("Unable to fetch data. Maximum retries reached: %d", h.MaxRetries)}
} }