-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.go
More file actions
36 lines (32 loc) · 1 KB
/
Copy pathmiddleware.go
File metadata and controls
36 lines (32 loc) · 1 KB
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
package circuitbreaker
import (
"errors"
"net/http"
)
// responseRecorder wraps http.ResponseWriter to capture the status code.
type responseRecorder struct {
http.ResponseWriter
statusCode int
}
// Middleware returns HTTP middleware that wraps requests with circuit breaker protection.
func Middleware(cb *CircuitBreaker) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := cb.Execute(func() (any, error) {
rec := &responseRecorder{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(rec, r)
if rec.statusCode >= 500 {
return nil, errors.New("internal server error")
}
return nil, nil
})
if errors.Is(err, ErrCircuitOpen) {
http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable)
}
})
}
}
func (r *responseRecorder) WriteHeader(statusCode int) {
r.statusCode = statusCode
r.ResponseWriter.WriteHeader(statusCode)
}