Skip to content
Snippets Groups Projects
Commit 9599a213 authored by ale's avatar ale
Browse files

Serve a JSON body on 400s for structured errors

Some errors (validation) have structured contents, not just an error
string, so we return them JSON-encoded along with a HTTP error 400.
parent 0b5acdb9
No related branches found
No related tags found
No related merge requests found
......@@ -100,6 +100,8 @@ func (v *validationError) JSON() []byte {
return data
}
// orNil solves the problem with nil-wrapping interfaces by returning
// an unwrapped nil if the validationError is nil.
func (v *validationError) orNil() error {
if v == nil {
return nil
......
......@@ -70,6 +70,10 @@ func New(service *as.AccountService, backend as.Backend) *APIServer {
var emptyResponse struct{}
type jsonError interface {
JSON() []byte
}
func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Create a new empty request object based on the request
// path, then decode the HTTP request JSON body onto it.
......@@ -85,7 +89,15 @@ func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
resp, err := s.service.Handle(req.Context(), r)
if err != nil {
http.Error(w, err.Error(), errToStatus(err))
// Handle structured errors, serve a JSON response.
status := errToStatus(err)
if jerr, ok := err.(jsonError); ok {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
w.Write(jerr.JSON()) // nolint
} else {
http.Error(w, err.Error(), status)
}
} else {
// Don't send nulls, send empty dicts instead.
if resp == nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment