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 { ...@@ -100,6 +100,8 @@ func (v *validationError) JSON() []byte {
return data 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 { func (v *validationError) orNil() error {
if v == nil { if v == nil {
return nil return nil
......
...@@ -70,6 +70,10 @@ func New(service *as.AccountService, backend as.Backend) *APIServer { ...@@ -70,6 +70,10 @@ func New(service *as.AccountService, backend as.Backend) *APIServer {
var emptyResponse struct{} var emptyResponse struct{}
type jsonError interface {
JSON() []byte
}
func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Create a new empty request object based on the request // Create a new empty request object based on the request
// path, then decode the HTTP request JSON body onto it. // path, then decode the HTTP request JSON body onto it.
...@@ -85,7 +89,15 @@ func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -85,7 +89,15 @@ func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
resp, err := s.service.Handle(req.Context(), r) resp, err := s.service.Handle(req.Context(), r)
if err != nil { 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 { } else {
// Don't send nulls, send empty dicts instead. // Don't send nulls, send empty dicts instead.
if resp == nil { if resp == nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment