Archived
1
0

Preserve HTTP staus codes in errors if possible

Dropbox being a REST driven service often returns useful information
in the HTTP error code.  Make sure we return these in a custom Error
type if possible.
This commit is contained in:
Nick Craig-Wood 2014-07-13 10:27:02 +01:00
parent 8022b93829
commit 8f46d993e2

View File

@ -231,6 +231,31 @@ func (db *Dropbox) Auth() error {
return err
}
// Error - all errors generated by HTTP transactions are of this type.
// Other error may be passed on from library functions though.
type Error struct {
StatusCode int // HTTP status code
Text string
}
// Error satisfy the error interface.
func (e *Error) Error() string {
return e.Text
}
// newError make a new error from a string.
func newError(StatusCode int, Text string) *Error {
return &Error{
StatusCode: StatusCode,
Text: Text,
}
}
// newErrorf makes a new error from sprintf parameters.
func newErrorf(StatusCode int, Text string, Parameters ...interface{}) *Error {
return newError(StatusCode, fmt.Sprintf(Text, Parameters...))
}
func getResponse(r *http.Response) ([]byte, error) {
var e requestError
var b []byte
@ -245,17 +270,17 @@ func getResponse(r *http.Response) ([]byte, error) {
if err = json.Unmarshal(b, &e); err == nil {
switch v := e.Error.(type) {
case string:
return nil, fmt.Errorf("%s", v)
return nil, newErrorf(r.StatusCode, "%s", v)
case map[string]interface{}:
for param, reason := range v {
if reasonstr, ok := reason.(string); ok {
return nil, fmt.Errorf("%s: %s", param, reasonstr)
return nil, newErrorf(r.StatusCode, "%s: %s", param, reasonstr)
}
}
return nil, fmt.Errorf("wrong parameter")
return nil, newErrorf(r.StatusCode, "wrong parameter")
}
}
return nil, fmt.Errorf("unexpected HTTP status code %d", r.StatusCode)
return nil, newErrorf(r.StatusCode, "unexpected HTTP status code %d")
}
// CommitChunkedUpload ends the chunked upload by giving a name to the UploadID.
@ -435,7 +460,7 @@ func (db *Dropbox) Thumbnails(src, format, size string) (io.ReadCloser, int64, *
return nil, 0, nil, os.ErrNotExist
case http.StatusUnsupportedMediaType:
response.Body.Close()
return nil, 0, nil, fmt.Errorf("the image located at '%s' cannot be converted to a thumbnail", src)
return nil, 0, nil, newErrorf(response.StatusCode, "the image located at '%s' cannot be converted to a thumbnail", src)
}
json.Unmarshal([]byte(response.Header.Get("x-dropbox-metadata")), &entry)
return response.Body, response.ContentLength, &entry, err