all repos — homestead @ c5e63c13cbc74fe27dca04bd004ea75a51f71763

Code for my website

internal/http/mux.go (view raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package http

import (
	"net/http"

	"go.alanpearce.eu/x/log"
)

type WebHandler func(http.ResponseWriter, *http.Request) *Error
type ErrorHandler func(*Error, http.ResponseWriter, *http.Request)

type ServeMux struct {
	log          *log.Logger
	errorHandler ErrorHandler
	*http.ServeMux
}

func NewServeMux() *ServeMux {
	return &ServeMux{
		ServeMux: http.NewServeMux(),
		errorHandler: func(err *Error, w http.ResponseWriter, _ *http.Request) {
			http.Error(w, err.Message, err.Code)
		},
	}
}

func (sm *ServeMux) HandleFunc(pattern string, handler WebHandler) {
	sm.ServeMux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if fail := recover(); fail != nil {
				w.WriteHeader(http.StatusInternalServerError)
				sm.log.Error("runtime panic!", "error", fail)
			}
		}()
		if err := handler(w, r); err != nil {
			sm.errorHandler(err, w, r)
		}
	})
}

func (sm *ServeMux) HandleError(fn ErrorHandler) {
	sm.errorHandler = fn
}