forked from Ivasoft/traefik
retry only on real network errors
Now retries only happen when actual network errors occur and not only anymore based on the HTTP status code. This is because the backend could also send this status codes as their normal interface and in that case we don't want to retry.
This commit is contained in:
committed by
Ludovic Fernandez
parent
131d8dd765
commit
f79317a435
88
server/errorhandler_test.go
Normal file
88
server/errorhandler_test.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type timeoutError struct{}
|
||||
|
||||
func (e *timeoutError) Error() string { return "i/o timeout" }
|
||||
func (e *timeoutError) Timeout() bool { return true }
|
||||
func (e *timeoutError) Temporary() bool { return true }
|
||||
|
||||
func TestServeHTTP(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
err error
|
||||
wantHTTPStatus int
|
||||
wantNetErrRecorded bool
|
||||
}{
|
||||
{
|
||||
name: "net.Error",
|
||||
err: net.UnknownNetworkError("any network error"),
|
||||
wantHTTPStatus: http.StatusBadGateway,
|
||||
wantNetErrRecorded: true,
|
||||
},
|
||||
{
|
||||
name: "net.Error with Timeout",
|
||||
err: &timeoutError{},
|
||||
wantHTTPStatus: http.StatusGatewayTimeout,
|
||||
wantNetErrRecorded: true,
|
||||
},
|
||||
{
|
||||
name: "io.EOF",
|
||||
err: io.EOF,
|
||||
wantHTTPStatus: http.StatusBadGateway,
|
||||
wantNetErrRecorded: true,
|
||||
},
|
||||
{
|
||||
name: "custom error",
|
||||
err: errors.New("any error"),
|
||||
wantHTTPStatus: http.StatusInternalServerError,
|
||||
wantNetErrRecorded: false,
|
||||
},
|
||||
{
|
||||
name: "nil error",
|
||||
err: nil,
|
||||
wantHTTPStatus: http.StatusInternalServerError,
|
||||
wantNetErrRecorded: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
errorRecorder := &netErrorRecorder{}
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:3000/any", nil)
|
||||
|
||||
recordingErrorHandler := NewRecordingErrorHandler(errorRecorder)
|
||||
recordingErrorHandler.ServeHTTP(recorder, req, test.err)
|
||||
|
||||
if recorder.Code != test.wantHTTPStatus {
|
||||
t.Errorf("got HTTP status code %v, wanted %v", recorder.Code, test.wantHTTPStatus)
|
||||
}
|
||||
if errorRecorder.netErrorWasRecorded != test.wantNetErrRecorded {
|
||||
t.Errorf("net error recording wrong, got %v wanted %v", errorRecorder.netErrorWasRecorded, test.wantNetErrRecorded)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type netErrorRecorder struct {
|
||||
netErrorWasRecorded bool
|
||||
}
|
||||
|
||||
func (recorder *netErrorRecorder) Record(ctx context.Context) {
|
||||
recorder.netErrorWasRecorded = true
|
||||
}
|
||||
Reference in New Issue
Block a user