Skip to content

Commit 64b34dc

Browse files
yangzong18huiguangjun
authored andcommitted
Read error information from header (#369)
1 parent 72974c6 commit 64b34dc

File tree

4 files changed

+85
-19
lines changed

4 files changed

+85
-19
lines changed

oss/bucket_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,46 @@ func (s *OssBucketSuite) TestGetObjectMeta(c *C) {
17751775
c.Assert(err, NotNil)
17761776
}
17771777

1778+
// TestErrorFromHeader
1779+
func (s *OssBucketSuite) TestErrorFromHeader(c *C) {
1780+
objectName := objectNamePrefix + RandStr(8)
1781+
1782+
// Put
1783+
err := s.bucket.PutObject(objectName, strings.NewReader(""))
1784+
c.Assert(err, IsNil)
1785+
1786+
_, err = s.bucket.GetObject(objectName)
1787+
c.Assert(err, IsNil)
1788+
1789+
meta, err := s.bucket.GetObjectMeta(objectName)
1790+
c.Assert(err, IsNil)
1791+
c.Assert(len(meta) > 0, Equals, true)
1792+
1793+
exist, err := s.bucket.IsObjectExist(objectName)
1794+
c.Assert(err, IsNil)
1795+
c.Assert(exist, Equals, true)
1796+
err = s.bucket.DeleteObject(objectName)
1797+
c.Assert(err, IsNil)
1798+
1799+
_, err = s.bucket.GetObject(objectName)
1800+
c.Assert(err, NotNil)
1801+
c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
1802+
c.Assert(err.(ServiceError).Ec != "", Equals, true)
1803+
c.Assert(err.(ServiceError).RequestID != "", Equals, true)
1804+
c.Assert(err.(ServiceError).HostID != "", Equals, true)
1805+
1806+
exist, err = s.bucket.IsObjectExist(objectName)
1807+
c.Assert(err, IsNil)
1808+
c.Assert(exist, Equals, false)
1809+
1810+
_, err = s.bucket.GetObjectMeta("NotExistObject")
1811+
c.Assert(err, NotNil)
1812+
c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
1813+
c.Assert(err.(ServiceError).Ec != "", Equals, true)
1814+
c.Assert(err.(ServiceError).RequestID != "", Equals, true)
1815+
c.Assert(err.(ServiceError).HostID != "", Equals, true)
1816+
}
1817+
17781818
// TestGetObjectDetailedMeta
17791819
func (s *OssBucketSuite) TestGetObjectDetailedMeta(c *C) {
17801820
objectName := objectNamePrefix + RandStr(8)

oss/conn.go

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -506,27 +506,37 @@ func (conn Conn) handleResponse(resp *http.Response, crc hash.Hash64) (*Response
506506
if statusCode >= 400 && statusCode <= 505 {
507507
// 4xx and 5xx indicate that the operation has error occurred
508508
var respBody []byte
509+
var errorXml []byte
509510
respBody, err := readResponseBody(resp)
510511
if err != nil {
511512
return nil, err
512513
}
513-
514-
if len(respBody) == 0 {
514+
errorXml = respBody
515+
if len(respBody) == 0 && len(resp.Header.Get(HTTPHeaderOssErr)) > 0 {
516+
errorXml, err = base64.StdEncoding.DecodeString(resp.Header.Get(HTTPHeaderOssErr))
517+
if err != nil {
518+
errorXml = respBody
519+
}
520+
}
521+
if len(errorXml) == 0 {
515522
err = ServiceError{
516523
StatusCode: statusCode,
517524
RequestID: resp.Header.Get(HTTPHeaderOssRequestID),
525+
Ec: resp.Header.Get(HTTPHeaderOssEc),
518526
}
519527
} else {
520-
// Response contains storage service error object, unmarshal
521-
srvErr, errIn := serviceErrFromXML(respBody, resp.StatusCode,
528+
srvErr, errIn := serviceErrFromXML(errorXml, resp.StatusCode,
522529
resp.Header.Get(HTTPHeaderOssRequestID))
523-
if errIn != nil { // error unmarshaling the error response
524-
err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
530+
if errIn != nil { // error unmarshal the error response
531+
if len(resp.Header.Get(HTTPHeaderOssEc)) > 0 {
532+
err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s, ec = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID), resp.Header.Get(HTTPHeaderOssEc))
533+
} else {
534+
err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
535+
}
525536
} else {
526537
err = srvErr
527538
}
528539
}
529-
530540
return &Response{
531541
StatusCode: resp.StatusCode,
532542
Headers: resp.Header,
@@ -544,27 +554,37 @@ func (conn Conn) handleResponse(resp *http.Response, crc hash.Hash64) (*Response
544554
// (0,300) [308,400) [506,)
545555
// Other extended http StatusCode
546556
var respBody []byte
557+
var errorXml []byte
547558
respBody, err := readResponseBody(resp)
548559
if err != nil {
549560
return &Response{StatusCode: resp.StatusCode, Headers: resp.Header, Body: ioutil.NopCloser(bytes.NewReader(respBody))}, err
550561
}
551-
552-
if len(respBody) == 0 {
562+
errorXml = respBody
563+
if len(respBody) == 0 && len(resp.Header.Get(HTTPHeaderOssErr)) > 0 {
564+
errorXml, err = base64.StdEncoding.DecodeString(resp.Header.Get(HTTPHeaderOssErr))
565+
if err != nil {
566+
errorXml = respBody
567+
}
568+
}
569+
if len(errorXml) == 0 {
553570
err = ServiceError{
554571
StatusCode: statusCode,
555572
RequestID: resp.Header.Get(HTTPHeaderOssRequestID),
573+
Ec: resp.Header.Get(HTTPHeaderOssEc),
556574
}
557575
} else {
558-
// Response contains storage service error object, unmarshal
559-
srvErr, errIn := serviceErrFromXML(respBody, resp.StatusCode,
576+
srvErr, errIn := serviceErrFromXML(errorXml, resp.StatusCode,
560577
resp.Header.Get(HTTPHeaderOssRequestID))
561-
if errIn != nil { // error unmarshaling the error response
562-
err = fmt.Errorf("unkown response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
578+
if errIn != nil { // error unmarshal the error response
579+
if len(resp.Header.Get(HTTPHeaderOssEc)) > 0 {
580+
err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s, ec = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID), resp.Header.Get(HTTPHeaderOssEc))
581+
} else {
582+
err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
583+
}
563584
} else {
564585
err = srvErr
565586
}
566587
}
567-
568588
return &Response{
569589
StatusCode: resp.StatusCode,
570590
Headers: resp.Header,

oss/const.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ const (
207207
HttpHeaderOssDate = "X-Oss-Date"
208208
HttpHeaderOssContentSha256 = "X-Oss-Content-Sha256"
209209
HttpHeaderOssNotification = "X-Oss-Notification"
210+
HTTPHeaderOssEc = "X-Oss-Ec"
211+
HTTPHeaderOssErr = "X-Oss-Err"
210212
)
211213

212214
// HTTP Param

oss/error.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,22 @@ type ServiceError struct {
1515
RequestID string `xml:"RequestId"` // The UUID used to uniquely identify the request
1616
HostID string `xml:"HostId"` // The OSS server cluster's Id
1717
Endpoint string `xml:"Endpoint"`
18+
Ec string `xml:"EC"`
1819
RawMessage string // The raw messages from OSS
1920
StatusCode int // HTTP status code
21+
2022
}
2123

2224
// Error implements interface error
2325
func (e ServiceError) Error() string {
24-
if e.Endpoint == "" {
25-
return fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s",
26-
e.StatusCode, e.Code, e.Message, e.RequestID)
26+
errorStr := fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s", e.StatusCode, e.Code, e.Message, e.RequestID)
27+
if len(e.Endpoint) > 0 {
28+
errorStr = fmt.Sprintf("%s, Endpoint=%s", errorStr, e.Endpoint)
29+
}
30+
if len(e.Ec) > 0 {
31+
errorStr = fmt.Sprintf("%s, Ec=%s", errorStr, e.Ec)
2732
}
28-
return fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s, Endpoint=%s",
29-
e.StatusCode, e.Code, e.Message, e.RequestID, e.Endpoint)
33+
return errorStr
3034
}
3135

3236
// UnexpectedStatusCodeError is returned when a storage service responds with neither an error

0 commit comments

Comments
 (0)