func (srv *Server) WriteError(ctx context.Context, w http.ResponseWriter, err error) {
	if srv.ErrorWriter != nil {
		srv.ErrorWriter(ctx, w, err)
		return
	}
	errorMapper := srv.ErrorMapper
	if errorMapper == nil {
		errorMapper = DefaultErrorMapper
	}
	status, resp := errorMapper(ctx, err)
	err1 := WriteJSON(w, status, resp)
	if err1 == nil {
		return
	}
	status1, resp1 := errorMapper(ctx, errgo.Notef(err1, "cannot marshal error response %q", err))
	err2 := WriteJSON(w, status1, resp1)
	if err2 == nil {
		return
	}
	w.WriteHeader(http.StatusInternalServerError)
	w.Write([]byte(fmt.Sprintf("really cannot marshal error response %q: %v", err, err1)))
}
WriteError writes an error to a ResponseWriter and sets the HTTP
status code, using srv.ErrorMapper to determine the actually written
response.

It uses WriteJSON to write the error body returned from the
ErrorMapper so it is possible to add custom headers to the HTTP error
response by implementing HeaderSetter.
package httprequest
import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"reflect"
	"github.com/julienschmidt/httprouter"
	"golang.org/x/net/context"
	"gopkg.in/errgo.v1"
)
type Server struct {
	ErrorMapper func(ctxt context.Context, err error) (httpStatus int, errorBody interface{})
	ErrorWriter func(ctx context.Context, w http.ResponseWriter, err error)
}
type Handler struct {
	Method string
	Path   string
	Handle httprouter.Handle
}
type handlerFunc struct {
	unmarshal func(p Params) (reflect.Value, error)
	call func(fv, argv reflect.Value, p Params)
	method string
	pathPattern string
}
var (
	paramsType             = reflect.TypeOf(Params{})
	errorType              = reflect.TypeOf((*error)(nil)).Elem()
	contextType            = reflect.TypeOf((*context.Context)(nil)).Elem()
	httpResponseWriterType = reflect.TypeOf((*http.ResponseWriter)(nil)).Elem()
	httpHeaderType         = reflect.TypeOf(http.Header(nil))
	httpRequestType        = reflect.TypeOf((*http.Request)(nil))
	ioCloserType           = reflect.TypeOf((*io.Closer)(nil)).Elem()
)
func AddHandlers(r *httprouter.Router, hs []Handler) {
	for _, h := range hs {
		r.Handle(h.Method, h.Path, h.Handle)
	}
}
func (srv *Server) Handle(f interface{}) Handler {
	fv := reflect.ValueOf(f)
	hf, err := srv.handlerFunc(fv.Type(), nil)
	if err != nil {
		panic(errgo.Notef(err, "bad handler function"))
	}
	return Handler{
		Method: hf.method,
		Path:   hf.pathPattern,
		Handle: func(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
			ctx, cancel := contextFromRequest(req)
			defer cancel()
			p1 := Params{
				Response:    w,
				Request:     req,
				PathVar:     p,
				PathPattern: hf.pathPattern,
				Context:     ctx,
			}
			argv, err := hf.unmarshal(p1)
			if err != nil {
				srv.WriteError(ctx, w, err)
				return
			}
			hf.call(fv, argv, p1)
		},
	}
}
func (srv *Server) Handlers(f interface{}) []Handler {
	rootv := reflect.ValueOf(f)
	wt, argInterfacet, err := checkHandlersWrapperFunc(rootv)
	if err != nil {
		panic(errgo.Notef(err, "bad handler function"))
	}
	hasClose := wt.Implements(ioCloserType)
	hs := make([]Handler, 0, wt.NumMethod())
	for i := 0; i < wt.NumMethod(); i++ {
		i := i
		m := wt.Method(i)
		if m.PkgPath != "" {
			continue
		}
		if m.Name == "Close" {
			if !hasClose {
				panic(errgo.Newf("bad type for Close method (got %v want func(%v) error", m.Type, wt))
			}
			continue
		}
		h, err := srv.methodHandler(m, rootv, argInterfacet, hasClose)
		if err != nil {
			panic(err)
		}
		hs = append(hs, h)
	}
	if len(hs) == 0 {
		panic(errgo.Newf("no exported methods defined on %s", wt))
	}
	return hs
}
func (srv *Server) methodHandler(m reflect.Method, rootv reflect.Value, argInterfacet reflect.Type, hasClose bool) (Handler, error) {
	mt := withoutReceiver(m.Type)
	hf, err := srv.handlerFunc(mt, argInterfacet)
	if err != nil {
		return Handler{}, errgo.Notef(err, "bad type for method %s", m.Name)
	}
	if hf.method == "" || hf.pathPattern == "" {
		return Handler{}, errgo.Notef(err, "method %s does not specify route method and path", m.Name)
	}
	handler := func(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
		ctx, cancel := contextFromRequest(req)
		defer cancel()
		p1 := Params{
			Response:    w,
			Request:     req,
			PathVar:     p,
			PathPattern: hf.pathPattern,
			Context:     ctx,
		}
		inv, err := hf.unmarshal(p1)
		if err != nil {
			srv.WriteError(ctx, w, err)
			return
		}
		var outv []reflect.Value
		if argInterfacet != nil {
			outv = rootv.Call([]reflect.Value{
				reflect.ValueOf(p1),
				inv,
			})
		} else {
			outv = rootv.Call([]reflect.Value{
				reflect.ValueOf(p1),
			})
		}
		tv, ctxv, errv := outv[0], outv[1], outv[2]
		ctx1, _ := ctxv.Interface().(context.Context)
		if ctx1 != nil {
			ctx = ctx1
		}
		if !errv.IsNil() {
			srv.WriteError(ctx, w, errv.Interface().(error))
			return
		}
		if hasClose {
			defer tv.Interface().(io.Closer).Close()
		}
		hf.call(tv.Method(m.Index), inv, Params{
			Response:    w,
			Request:     req,
			PathVar:     p,
			PathPattern: hf.pathPattern,
			Context:     ctx,
		})
	}
	return Handler{
		Method: hf.method,
		Path:   hf.pathPattern,
		Handle: handler,
	}, nil
}
func checkHandlersWrapperFunc(fv reflect.Value) (returnt, argInterfacet reflect.Type, err error) {
	ft := fv.Type()
	if ft.Kind() != reflect.Func {
		return nil, nil, errgo.Newf("expected function, got %v", ft)
	}
	if fv.IsNil() {
		return nil, nil, errgo.Newf("function is nil")
	}
	if n := ft.NumIn(); n != 1 && n != 2 {
		return nil, nil, errgo.Newf("got %d arguments, want 1 or 2", n)
	}
	if n := ft.NumOut(); n != 3 {
		return nil, nil, errgo.Newf("function returns %d values, want (<T>, context.Context, error)", n)
	}
	if t := ft.In(0); t != paramsType {
		return nil, nil, errgo.Newf("invalid first argument, want httprequest.Params, got %v", t)
	}
	if ft.NumIn() > 1 {
		if t := ft.In(1); t.Kind() != reflect.Interface {
			return nil, nil, errgo.Newf("invalid second argument, want interface type, got %v", t)
		}
		argInterfacet = ft.In(1)
	}
	if t := ft.Out(1); !t.Implements(contextType) {
		return nil, nil, errgo.Newf("second return parameter of type %v does not implement context.Context", t)
	}
	if t := ft.Out(2); t != errorType {
		return nil, nil, errgo.Newf("invalid third return parameter, want error, got %v", t)
	}
	return ft.Out(0), argInterfacet, nil
}
func checkHandleType(t, argInterfacet reflect.Type) (*requestType, error) {
	if t.Kind() != reflect.Func {
		return nil, errgo.New("not a function")
	}
	if n := t.NumIn(); n != 1 && n != 2 {
		return nil, errgo.Newf("has %d parameters, need 1 or 2", t.NumIn())
	}
	if t.NumOut() > 2 {
		return nil, errgo.Newf("has %d result parameters, need 0, 1 or 2", t.NumOut())
	}
	if t.NumIn() == 2 {
		if t.In(0) != paramsType {
			return nil, errgo.Newf("first argument is %v, need httprequest.Params", t.In(0))
		}
	} else {
		if t.In(0) == paramsType {
			return nil, errgo.Newf("no argument parameter after Params argument")
		}
	}
	argt := t.In(t.NumIn() - 1)
	pt, err := getRequestType(argt)
	if err != nil {
		return nil, errgo.Notef(err, "last argument cannot be used for Unmarshal")
	}
	if argInterfacet != nil && !argt.Implements(argInterfacet) {
		return nil, errgo.Notef(err, "argument of type %v does not implement interface required by root handler %v", argt, argInterfacet)
	}
	if t.NumOut() > 0 {
		if et := t.Out(t.NumOut() - 1); et != errorType {
			return nil, errgo.Newf("final result parameter is %s, need error", et)
		}
	}
	return pt, nil
}
func (srv *Server) handlerFunc(ft, argInterfacet reflect.Type) (handlerFunc, error) {
	rt, err := checkHandleType(ft, argInterfacet)
	if err != nil {
		return handlerFunc{}, errgo.Mask(err)
	}
	return handlerFunc{
		unmarshal:   handlerUnmarshaler(ft, rt),
		call:        srv.handlerCaller(ft, rt),
		method:      rt.method,
		pathPattern: rt.path,
	}, nil
}
func handlerUnmarshaler(
	ft reflect.Type,
	rt *requestType,
) func(p Params) (reflect.Value, error) {
	argStructType := ft.In(ft.NumIn() - 1).Elem()
	return func(p Params) (reflect.Value, error) {
		if err := p.Request.ParseForm(); err != nil {
			return reflect.Value{}, errgo.WithCausef(err, ErrUnmarshal, "cannot parse HTTP request form")
		}
		argv := reflect.New(argStructType)
		if err := unmarshal(p, argv, rt); err != nil {
			return reflect.Value{}, errgo.NoteMask(err, "cannot unmarshal parameters", errgo.Is(ErrUnmarshal))
		}
		return argv, nil
	}
}
func (srv *Server) handlerCaller(
	ft reflect.Type,
	rt *requestType,
) func(fv, argv reflect.Value, p Params) {
	returnJSON := ft.NumOut() > 1
	needsParams := ft.In(0) == paramsType
	respond := srv.handlerResponder(ft)
	return func(fv, argv reflect.Value, p Params) {
		var rv []reflect.Value
		if needsParams {
			p := p
			if returnJSON {
				p.Response = headerOnlyResponseWriter{p.Response.Header()}
			}
			rv = fv.Call([]reflect.Value{
				reflect.ValueOf(p),
				argv,
			})
		} else {
			rv = fv.Call([]reflect.Value{
				argv,
			})
		}
		respond(p, rv)
	}
}
func (srv *Server) handlerResponder(ft reflect.Type) func(p Params, outv []reflect.Value) {
	switch ft.NumOut() {
	case 0:
		return func(Params, []reflect.Value) {}
	case 1:
		return func(p Params, outv []reflect.Value) {
			if err := outv[0].Interface(); err != nil {
				srv.WriteError(p.Context, p.Response, err.(error))
			}
		}
	case 2:
		return func(p Params, outv []reflect.Value) {
			if err := outv[1].Interface(); err != nil {
				srv.WriteError(p.Context, p.Response, err.(error))
				return
			}
			if err := WriteJSON(p.Response, http.StatusOK, outv[0].Interface()); err != nil {
				srv.WriteError(p.Context, p.Response, err)
			}
		}
	default:
		panic("unreachable")
	}
}
func ToHTTP(h httprouter.Handle) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		h(w, req, nil)
	})
}
type JSONHandler func(Params) (interface{}, error)
type ErrorHandler func(Params) error
func (srv *Server) HandleJSON(handle JSONHandler) httprouter.Handle {
	return func(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
		ctx, cancel := contextFromRequest(req)
		defer cancel()
		val, err := handle(Params{
			Response: headerOnlyResponseWriter{w.Header()},
			Request:  req,
			PathVar:  p,
			Context:  ctx,
		})
		if err == nil {
			if err = WriteJSON(w, http.StatusOK, val); err == nil {
				return
			}
		}
		srv.WriteError(ctx, w, err)
	}
}
func (srv *Server) HandleErrors(handle ErrorHandler) httprouter.Handle {
	return func(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
		w1 := responseWriter{
			ResponseWriter: w,
		}
		ctx, cancel := contextFromRequest(req)
		defer cancel()
		if err := handle(Params{
			Response: &w1,
			Request:  req,
			PathVar:  p,
			Context:  ctx,
		}); err != nil {
			if w1.headerWritten {
				return
			}
			srv.WriteError(ctx, w, err)
		}
	}
}