Update util dep
MODIFY
vendor/manifest
vendor/manifest
{
"importpath": "github.com/matrix-org/util",
"repository": "https://github.com/matrix-org/util",
- "revision": "0bbc3896e02031e7e7338948b73ce891aa73ab2b",
+ "revision": "4de125c773716ad380f2f80cc6c04789ef4c906a",
"branch": "master"
},
{

MODIFY
vendor/src/github.com/matrix-org/util/error.go
vendor/src/github.com/matrix-org/util/error.go
@@ -5,8 +5,14 @@ import "fmt"
// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
type HTTPError struct {
WrappedError error
+ // A human-readable message to return to the client in a JSON response. This
+ // is ignored if JSON is supplied.
Message string
+ // HTTP status code.
Code int
+ // JSON represents the JSON that should be serialized and sent to the client
+ // instead of the given Message.
+ JSON interface{}
}
func (e HTTPError) Error() string {

MODIFY
vendor/src/github.com/matrix-org/util/json.go
vendor/src/github.com/matrix-org/util/json.go
@@ -68,7 +68,10 @@ func Protect(handler http.HandlerFunc) http.HandlerFunc {
"Request panicked!\n%s", debug.Stack(),
)
jsonErrorResponse(
- w, req, &HTTPError{nil, "Internal Server Error", 500},
+ w, req, &HTTPError{
+ Message: "Internal Server Error",
+ Code: 500,
+ },
)
}
}()
@@ -112,7 +115,10 @@ func MakeJSONAPI(handler JSONRequestHandler) http.HandlerFunc {
if !ok {
r, err := json.Marshal(res)
if err != nil {
- jsonErrorResponse(w, req, &HTTPError{nil, "Failed to serialise response as JSON", 500})
+ jsonErrorResponse(w, req, &HTTPError{
+ Message: "Failed to serialise response as JSON",
+ Code: 500,
+ })
return
}
resBytes = r
@@ -135,9 +141,23 @@ func jsonErrorResponse(w http.ResponseWriter, req *http.Request, httpErr *HTTPEr
w.WriteHeader(httpErr.Code) // Set response code
- r, err := json.Marshal(&JSONError{
+ var err error
+ var r []byte
+ if httpErr.JSON != nil {
+ r, err = json.Marshal(httpErr.JSON)
+ if err != nil {
+ // failed to marshal the supplied interface. Whine and fallback to the HTTP message.
+ logger.WithError(err).Error("Failed to marshal HTTPError.JSON")
+ }
+ }
+
+ // failed to marshal or no custom JSON was supplied, send message JSON.
+ if err != nil || httpErr.JSON == nil {
+ r, err = json.Marshal(&JSONError{
Message: httpErr.Message,
})
+ }
+
if err != nil {
// We should never fail to marshal the JSON error response, but in this event just skip
// marshalling altogether

MODIFY
vendor/src/github.com/matrix-org/util/json_test.go
vendor/src/github.com/matrix-org/util/json_test.go
@@ -29,12 +29,26 @@ func TestMakeJSONAPI(t *testing.T) {
ExpectCode int
ExpectJSON string
}{
- {nil, &HTTPError{nil, "Everything is broken", 500}, 500, `{"message":"Everything is broken"}`}, // Error return values
- {nil, &HTTPError{nil, "Not here", 404}, 404, `{"message":"Not here"}`}, // With different status codes
- {&MockResponse{"yep"}, nil, 200, `{"foo":"yep"}`}, // Success return values
- {[]MockResponse{{"yep"}, {"narp"}}, nil, 200, `[{"foo":"yep"},{"foo":"narp"}]`}, // Top-level array success values
- {[]byte(`actually bytes`), nil, 200, `actually bytes`}, // raw []byte escape hatch
- {func(cannotBe, marshalled string) {}, nil, 500, `{"message":"Failed to serialise response as JSON"}`}, // impossible marshal
+ // Error message return values
+ {nil, &HTTPError{nil, "Everything is broken", 500, nil}, 500, `{"message":"Everything is broken"}`},
+ // Error JSON return values
+ {nil, &HTTPError{nil, "Everything is broken", 500, struct {
+ Foo string `json:"foo"`
+ }{"yep"}}, 500, `{"foo":"yep"}`},
+ // Error JSON return values which fail to be marshalled should fallback to text
+ {nil, &HTTPError{nil, "Everything is broken", 500, struct {
+ Foo interface{} `json:"foo"`
+ }{func(cannotBe, marshalled string) {}}}, 500, `{"message":"Everything is broken"}`},
+ // With different status codes
+ {nil, &HTTPError{nil, "Not here", 404, nil}, 404, `{"message":"Not here"}`},
+ // Success return values
+ {&MockResponse{"yep"}, nil, 200, `{"foo":"yep"}`},
+ // Top-level array success values
+ {[]MockResponse{{"yep"}, {"narp"}}, nil, 200, `[{"foo":"yep"},{"foo":"narp"}]`},
+ // raw []byte escape hatch
+ {[]byte(`actually bytes`), nil, 200, `actually bytes`},
+ // impossible marshal
+ {func(cannotBe, marshalled string) {}, nil, 500, `{"message":"Failed to serialise response as JSON"}`},
}
for _, tst := range tests {
@@ -58,7 +72,7 @@ func TestMakeJSONAPI(t *testing.T) {
func TestMakeJSONAPIRedirect(t *testing.T) {
log.SetLevel(log.PanicLevel) // suppress logs in test output
mock := MockJSONRequestHandler{func(req *http.Request) (interface{}, *HTTPError) {
- return nil, &HTTPError{nil, "https://matrix.org", 302}
+ return nil, &HTTPError{nil, "https://matrix.org", 302, nil}
}}
mockReq, _ := http.NewRequest("GET", "http://example.com/foo", nil)
mockWriter := httptest.NewRecorder()

Update util dep