Update util dep

main
Kegan Dougal 2017-02-21 17:17:56 +00:00
parent 51f9741b34
commit 9e6127d12a
4 changed files with 55 additions and 15 deletions

2
vendor/manifest vendored
View File

@ -92,7 +92,7 @@
{
"importpath": "github.com/matrix-org/util",
"repository": "https://github.com/matrix-org/util",
"revision": "0bbc3896e02031e7e7338948b73ce891aa73ab2b",
"revision": "4de125c773716ad380f2f80cc6c04789ef4c906a",
"branch": "master"
},
{

View File

@ -5,8 +5,14 @@ import "fmt"
// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
type HTTPError struct {
WrappedError error
Message string
Code int
// 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 {

View File

@ -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{
Message: httpErr.Message,
})
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

View File

@ -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()