-
Notifications
You must be signed in to change notification settings - Fork 24
/
injector_error.go
80 lines (66 loc) · 1.93 KB
/
injector_error.go
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package fault
import (
"errors"
"net/http"
"reflect"
)
var (
// ErrInvalidHTTPCode when an invalid status code is provided.
ErrInvalidHTTPCode = errors.New("not a valid http status code")
)
// ErrorInjector responds with an http status code and message.
type ErrorInjector struct {
statusCode int
statusText string
reporter Reporter
}
// ErrorInjectorOption configures an ErrorInjector.
type ErrorInjectorOption interface {
applyErrorInjector(i *ErrorInjector) error
}
type statusTextOption string
func (o statusTextOption) applyErrorInjector(i *ErrorInjector) error {
i.statusText = string(o)
return nil
}
// WithStatusText sets custom status text to write.
func WithStatusText(t string) ErrorInjectorOption {
return statusTextOption(t)
}
func (o reporterOption) applyErrorInjector(i *ErrorInjector) error {
i.reporter = o.reporter
return nil
}
// NewErrorInjector returns an ErrorInjector that reponds with a status code.
func NewErrorInjector(code int, opts ...ErrorInjectorOption) (*ErrorInjector, error) {
const placeholderStatusText = "go-fault: replace with default code text"
// set defaults
ei := &ErrorInjector{
statusCode: code,
statusText: placeholderStatusText,
reporter: NewNoopReporter(),
}
// apply options
for _, opt := range opts {
err := opt.applyErrorInjector(ei)
if err != nil {
return nil, err
}
}
// check options
if http.StatusText(ei.statusCode) == "" {
return nil, ErrInvalidHTTPCode
}
if ei.statusText == placeholderStatusText {
ei.statusText = http.StatusText(ei.statusCode)
}
return ei, nil
}
// Handler responds with the configured status code and text.
func (i *ErrorInjector) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
go i.reporter.Report(reflect.ValueOf(*i).Type().Name(), StateStarted)
http.Error(w, i.statusText, i.statusCode)
go i.reporter.Report(reflect.ValueOf(*i).Type().Name(), StateFinished)
})
}