Skip to content

proposal: net/http: customizable response for server errors #21548

@theory

Description

@theory

I've written a little REST server on net/http that's supposed to only ever return JSON contents. At least, that's what the parts I wrote do. However, there are certain errors that net/http encounters before my code is ever called. In those situations, I have no access to any code to determine what the content type and message should be for a given error. For example, take this stupid simple implementation:

package main

import (
	"encoding/json"
	"net/http"
)

type Server struct{}

func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(http.StatusText(http.StatusOK)); err != nil {
		panic(err)
	}
}

func main() {
	http.ListenAndServe(":8080", &Server{})
}

If I submit a request with borked headers (this one has a wayward newline in the Authorization header), my ServeHTTP() method is never called, presumably because there's an error when parsing the request to create the Request object:

> curl -i -H 'Authorization: Basic hi
there' 'http://localhost:8080/'
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad Request

This makes complete sense to me, but if I'm creating an API with a contract to only ever return JSON, I'd like to have some way to plug into this error response and set the content-type and the body. I think the same challenge exists for Not Found errors. Perhaps there could be special handlers to configure these situations, similar to how Gorilla mux provides an assignable NotFoundHandler field in its Router object?

I'm not sure exactly what a generalized interface would look like for such error handlers (methods on Handler protocol?), but some way to hook in and get some control over net/http-initiated error responses would be very useful for guaranteeing the content-type contract of a web API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions