Skip to content

Commit 49324dc

Browse files
authored
Fall back to XML errors (minio#33)
MinIO may return XML errors. If JSON parsing fails, try XML as well. Example: ``` λ mc admin inspect local2/mybucket/file/../../* mc: <ERROR> Unable to inspect file. Failed to parse server response: invalid character '<' looking for beginning of value. ``` Error returned by generic handler `setRequestValidityHandler`. After: ``` λ go build&&mc admin inspect local2/mybucket/file/../../* mc: <ERROR> Unable to inspect file. Resource name contains bad components such as ".." or ".". ``` Also print content of unparsable content, like HTML, but at limited length.
1 parent 4cef8ab commit 49324dc

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

api-error-response.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
package madmin
1818

1919
import (
20+
"encoding/hex"
21+
"encoding/json"
2022
"encoding/xml"
2123
"fmt"
24+
"io"
25+
"io/ioutil"
2226
"net/http"
27+
"unicode/utf8"
2328
)
2429

2530
/* **** SAMPLE ERROR RESPONSE ****
@@ -61,20 +66,42 @@ const (
6166
// httpRespToErrorResponse returns a new encoded ErrorResponse
6267
// structure as error.
6368
func httpRespToErrorResponse(resp *http.Response) error {
64-
if resp == nil {
69+
if resp == nil || resp.Body == nil {
6570
msg := "Response is empty. " + reportIssue
6671
return ErrInvalidArgument(msg)
6772
}
68-
var errResp ErrorResponse
69-
// Decode the json error
70-
err := jsonDecoder(resp.Body, &errResp)
73+
74+
defer closeResponse(resp)
75+
// Limit to 100K
76+
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 100<<10))
7177
if err != nil {
7278
return ErrorResponse{
7379
Code: resp.Status,
74-
Message: fmt.Sprintf("Failed to parse server response: %s.", err),
80+
Message: fmt.Sprintf("Failed to read server response: %s.", err),
81+
}
82+
}
83+
84+
var errResp ErrorResponse
85+
// Decode the json error
86+
err = json.Unmarshal(body, &errResp)
87+
if err != nil {
88+
// We might get errors as XML, try that.
89+
xmlErr := xml.Unmarshal(body, &errResp)
90+
91+
if xmlErr != nil {
92+
bodyString := string(body)
93+
if !utf8.Valid(body) {
94+
bodyString = hex.EncodeToString(body)
95+
}
96+
if len(bodyString) > 1024 {
97+
bodyString = bodyString[:1021] + "..."
98+
}
99+
return ErrorResponse{
100+
Code: resp.Status,
101+
Message: fmt.Sprintf("Failed to parse server response (%s): %s", err.Error(), bodyString),
102+
}
75103
}
76104
}
77-
closeResponse(resp)
78105
return errResp
79106
}
80107

0 commit comments

Comments
 (0)