Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(675)

Side by Side Diff: common/lhttp/client.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: copyright Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package lhttp 5 package lhttp
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/json" 9 "encoding/json"
10 "fmt" 10 "fmt"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 attempts++ 76 attempts++
77 req, err := rgen() 77 req, err := rgen()
78 if err != nil { 78 if err != nil {
79 return err 79 return err
80 } 80 }
81 81
82 resp, err := c.Do(req) 82 resp, err := c.Do(req)
83 if err != nil { 83 if err != nil {
84 // Retry every error. This is sad when you speci fy an invalid hostname but 84 // Retry every error. This is sad when you speci fy an invalid hostname but
85 // it's better than failing when DNS resolution is flaky. 85 // it's better than failing when DNS resolution is flaky.
86 » » » » return errorHandler(nil, errors.WrapTransient(er r)) 86 » » » » return errorHandler(nil, retry.Tag.Apply(err))
87 } 87 }
88 status = resp.StatusCode 88 status = resp.StatusCode
89 89
90 switch { 90 switch {
91 case status == 408, status == 429, status >= 500: 91 case status == 408, status == 429, status >= 500:
92 // The HTTP status code means the request should be retried. 92 // The HTTP status code means the request should be retried.
93 » » » » err = errors.WrapTransient( 93 » » » » err = errors.Reason("http request failed: %(text )s (HTTP %(code)d)").
94 » » » » » fmt.Errorf("http request failed: %s (HTT P %d)", http.StatusText(status), status)) 94 » » » » » D("text", http.StatusText(status)).D("co de", status).Tag(retry.Tag).Err()
95 case status == 404 && strings.HasPrefix(req.URL.Path, "/ _ah/api/"): 95 case status == 404 && strings.HasPrefix(req.URL.Path, "/ _ah/api/"):
96 // Endpoints occasionally return 404 on valid re quests! 96 // Endpoints occasionally return 404 on valid re quests!
97 logging.Infof(ctx, "lhttp.Do() got a Cloud Endpo ints 404: %#v", resp.Header) 97 logging.Infof(ctx, "lhttp.Do() got a Cloud Endpo ints 404: %#v", resp.Header)
98 » » » » err = errors.WrapTransient( 98 » » » » err = errors.Reason("http request failed (endpoi nts): %(text)s (HTTP %(code)d)").
99 » » » » » fmt.Errorf("http request failed (endpoin ts): %s (HTTP %d)", http.StatusText(status), status)) 99 » » » » » D("text", http.StatusText(status)).D("co de", status).Tag(retry.Tag).Err()
100 case status >= 400: 100 case status >= 400:
101 // Any other failure code is a hard failure. 101 // Any other failure code is a hard failure.
102 err = fmt.Errorf("http request failed: %s (HTTP %d)", http.StatusText(status), status) 102 err = fmt.Errorf("http request failed: %s (HTTP %d)", http.StatusText(status), status)
103 default: 103 default:
104 // The handler may still return a retry.Error to indicate that the request 104 // The handler may still return a retry.Error to indicate that the request
105 // should be retried even on successful status c ode. 105 // should be retried even on successful status c ode.
106 return handler(resp) 106 return handler(resp)
107 } 107 }
108 108
109 return errorHandler(resp, err) 109 return errorHandler(resp, err)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // Non-retriable. 150 // Non-retriable.
151 return fmt.Errorf("unexpected Content-Type, expected \"% s\", got \"%s\"", jsonContentType, ct) 151 return fmt.Errorf("unexpected Content-Type, expected \"% s\", got \"%s\"", jsonContentType, ct)
152 } 152 }
153 if out == nil { 153 if out == nil {
154 // The client doesn't care about the response. Still ens ure the response 154 // The client doesn't care about the response. Still ens ure the response
155 // is valid json. 155 // is valid json.
156 out = &map[string]interface{}{} 156 out = &map[string]interface{}{}
157 } 157 }
158 if err := json.NewDecoder(resp.Body).Decode(out); err != nil { 158 if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
159 // Retriable. 159 // Retriable.
160 » » » return errors.WrapTransient(fmt.Errorf("bad response %s: %s", url, err)) 160 » » » return errors.Annotate(err).Reason("bad response %(url)s ").
161 » » » » D("url", url).Tag(retry.Tag).Err()
161 } 162 }
162 return nil 163 return nil
163 }, nil), nil 164 }, nil), nil
164 } 165 }
165 166
166 // GetJSON is a shorthand. It returns the HTTP status code and error if any. 167 // GetJSON is a shorthand. It returns the HTTP status code and error if any.
167 func GetJSON(ctx context.Context, rFn retry.Factory, c *http.Client, url string, out interface{}) (int, error) { 168 func GetJSON(ctx context.Context, rFn retry.Factory, c *http.Client, url string, out interface{}) (int, error) {
168 req, err := NewRequestJSON(ctx, c, rFn, url, "GET", nil, nil, out) 169 req, err := NewRequestJSON(ctx, c, rFn, url, "GET", nil, nil, out)
169 if err != nil { 170 if err != nil {
170 return 0, err 171 return 0, err
171 } 172 }
172 return req() 173 return req()
173 } 174 }
174 175
175 // PostJSON is a shorthand. It returns the HTTP status code and error if any. 176 // PostJSON is a shorthand. It returns the HTTP status code and error if any.
176 func PostJSON(ctx context.Context, rFn retry.Factory, c *http.Client, url string , headers map[string]string, in, out interface{}) (int, error) { 177 func PostJSON(ctx context.Context, rFn retry.Factory, c *http.Client, url string , headers map[string]string, in, out interface{}) (int, error) {
177 req, err := NewRequestJSON(ctx, c, rFn, url, "POST", headers, in, out) 178 req, err := NewRequestJSON(ctx, c, rFn, url, "POST", headers, in, out)
178 if err != nil { 179 if err != nil {
179 return 0, err 180 return 0, err
180 } 181 }
181 return req() 182 return req()
182 } 183 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698