Skip to content

Commit

Permalink
Fix storage error reporting for unexpected status codes. (#956)
Browse files Browse the repository at this point in the history
For cases where a response contains an unexpected HTTP status code the
response body will contain extended failure information.  Make this
information available for better diagnosis.
Replaced internal type storageResponse with http.Response as it provided
no value and made the code more complicated.
Added Inner() method to UnexpectedStatusCodeError.
  • Loading branch information
jhendrixMSFT authored Jan 10, 2018
1 parent ef777d1 commit ef92a8b
Show file tree
Hide file tree
Showing 20 changed files with 283 additions and 296 deletions.
68 changes: 34 additions & 34 deletions storage/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ func (b *Blob) Exists() (bool, error) {
headers := b.Container.bsc.client.getStandardHeaders()
resp, err := b.Container.bsc.client.exec(http.MethodHead, uri, headers, nil, b.Container.bsc.auth)
if resp != nil {
defer readAndCloseBody(resp.body)
if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
return resp.statusCode == http.StatusOK, nil
defer readAndCloseBody(resp.Body)
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
return resp.StatusCode == http.StatusOK, nil
}
}
return false, err
Expand Down Expand Up @@ -208,13 +208,13 @@ func (b *Blob) Get(options *GetBlobOptions) (io.ReadCloser, error) {
return nil, err
}

if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
return nil, err
}
if err := b.writeProperties(resp.headers, true); err != nil {
return resp.body, err
if err := b.writeProperties(resp.Header, true); err != nil {
return resp.Body, err
}
return resp.body, nil
return resp.Body, nil
}

// GetRange reads the specified range of a blob to a stream. The bytesRange
Expand All @@ -228,18 +228,18 @@ func (b *Blob) GetRange(options *GetBlobRangeOptions) (io.ReadCloser, error) {
return nil, err
}

if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil {
if err := checkRespCode(resp, []int{http.StatusPartialContent}); err != nil {
return nil, err
}
// Content-Length header should not be updated, as the service returns the range length
// (which is not alwys the full blob length)
if err := b.writeProperties(resp.headers, false); err != nil {
return resp.body, err
if err := b.writeProperties(resp.Header, false); err != nil {
return resp.Body, err
}
return resp.body, nil
return resp.Body, nil
}

func (b *Blob) getRange(options *GetBlobRangeOptions) (*storageResponse, error) {
func (b *Blob) getRange(options *GetBlobRangeOptions) (*http.Response, error) {
params := url.Values{}
headers := b.Container.bsc.client.getStandardHeaders()

Expand Down Expand Up @@ -293,13 +293,13 @@ func (b *Blob) CreateSnapshot(options *SnapshotOptions) (snapshotTimestamp *time
if err != nil || resp == nil {
return nil, err
}
defer readAndCloseBody(resp.body)
defer readAndCloseBody(resp.Body)

if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil {
if err := checkRespCode(resp, []int{http.StatusCreated}); err != nil {
return nil, err
}

snapshotResponse := resp.headers.Get(http.CanonicalHeaderKey("x-ms-snapshot"))
snapshotResponse := resp.Header.Get(http.CanonicalHeaderKey("x-ms-snapshot"))
if snapshotResponse != "" {
snapshotTimestamp, err := time.Parse(time.RFC3339, snapshotResponse)
if err != nil {
Expand Down Expand Up @@ -340,12 +340,12 @@ func (b *Blob) GetProperties(options *GetBlobPropertiesOptions) error {
if err != nil {
return err
}
defer readAndCloseBody(resp.body)
defer readAndCloseBody(resp.Body)

if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
return err
}
return b.writeProperties(resp.headers, true)
return b.writeProperties(resp.Header, true)
}

func (b *Blob) writeProperties(h http.Header, includeContentLen bool) error {
Expand Down Expand Up @@ -463,8 +463,8 @@ func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error {
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusOK})
defer readAndCloseBody(resp.Body)
return checkRespCode(resp, []int{http.StatusOK})
}

// SetBlobMetadataOptions includes the options for a set blob metadata operation
Expand Down Expand Up @@ -501,8 +501,8 @@ func (b *Blob) SetMetadata(options *SetBlobMetadataOptions) error {
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusOK})
defer readAndCloseBody(resp.Body)
return checkRespCode(resp, []int{http.StatusOK})
}

// GetBlobMetadataOptions includes the options for a get blob metadata operation
Expand Down Expand Up @@ -538,13 +538,13 @@ func (b *Blob) GetMetadata(options *GetBlobMetadataOptions) error {
if err != nil {
return err
}
defer readAndCloseBody(resp.body)
defer readAndCloseBody(resp.Body)

if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
return err
}

b.writeMetadata(resp.headers)
b.writeMetadata(resp.Header)
return nil
}

Expand Down Expand Up @@ -574,8 +574,8 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error {
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
defer readAndCloseBody(resp.Body)
return checkRespCode(resp, []int{http.StatusAccepted})
}

// DeleteIfExists deletes the given blob from the specified container If the
Expand All @@ -585,15 +585,15 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error {
func (b *Blob) DeleteIfExists(options *DeleteBlobOptions) (bool, error) {
resp, err := b.delete(options)
if resp != nil {
defer readAndCloseBody(resp.body)
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
return resp.statusCode == http.StatusAccepted, nil
defer readAndCloseBody(resp.Body)
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
return resp.StatusCode == http.StatusAccepted, nil
}
}
return false, err
}

func (b *Blob) delete(options *DeleteBlobOptions) (*storageResponse, error) {
func (b *Blob) delete(options *DeleteBlobOptions) (*http.Response, error) {
params := url.Values{}
headers := b.Container.bsc.client.getStandardHeaders()

Expand Down Expand Up @@ -621,9 +621,9 @@ func pathForResource(container, name string) string {
return fmt.Sprintf("/%s", container)
}

func (b *Blob) respondCreation(resp *storageResponse, bt BlobType) error {
readAndCloseBody(resp.body)
err := checkRespCode(resp.statusCode, []int{http.StatusCreated})
func (b *Blob) respondCreation(resp *http.Response, bt BlobType) error {
defer readAndCloseBody(resp.Body)
err := checkRespCode(resp, []int{http.StatusCreated})
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion storage/blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ func (b *Blob) putSingleBlockBlob(chunk []byte) error {
if err != nil {
return err
}
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
return checkRespCode(resp, []int{http.StatusCreated})
}

func blobName(c *chk.C, extras ...string) string {
Expand Down
4 changes: 2 additions & 2 deletions storage/blobserviceclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*Con
if err != nil {
return nil, err
}
defer resp.body.Close()
err = xmlUnmarshal(resp.body, &outAlias)
defer resp.Body.Close()
err = xmlUnmarshal(resp.Body, &outAlias)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions storage/blockblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ func (b *Blob) PutBlockList(blocks []Block, options *PutBlockListOptions) error
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
defer readAndCloseBody(resp.Body)
return checkRespCode(resp, []int{http.StatusCreated})
}

// GetBlockListOptions includes the options for a get block list operation
Expand Down Expand Up @@ -263,8 +263,8 @@ func (b *Blob) GetBlockList(blockType BlockListType, options *GetBlockListOption
if err != nil {
return out, err
}
defer resp.body.Close()
defer resp.Body.Close()

err = xmlUnmarshal(resp.body, &out)
err = xmlUnmarshal(resp.Body, &out)
return out, err
}
Loading

0 comments on commit ef92a8b

Please sign in to comment.