Replace balancer panic with deferred error; test HealthChecker
A malformed endpoint URL panicked inside Transport, crashing the host app (often at startup from external config). Capture the parse error and surface it from the transport on first use instead. Add the previously untested HealthChecker coverage (initial probe, recovery, Stop termination, unknown endpoint), raising balancer coverage from ~41% to ~87%. Default the health probe path to /healthz to match this library's own server.
This commit is contained in:
@@ -55,12 +55,19 @@ func Transport(endpoints []Endpoint, opts ...Option) (middleware.Middleware, *Cl
|
||||
opt(o)
|
||||
}
|
||||
|
||||
// Pre-parse endpoint URLs once at construction time.
|
||||
// Pre-parse endpoint URLs once at construction time. A malformed URL is a
|
||||
// configuration error: rather than panicking (which would crash the host
|
||||
// application, often at startup from external config), we capture the
|
||||
// error and surface it from the transport on first use.
|
||||
parsed := make(map[string]*url.URL, len(endpoints))
|
||||
var parseErr error
|
||||
for _, ep := range endpoints {
|
||||
u, err := url.Parse(ep.URL)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("balancer: invalid endpoint URL %q: %v", ep.URL, err))
|
||||
if parseErr == nil {
|
||||
parseErr = fmt.Errorf("balancer: invalid endpoint URL %q: %w", ep.URL, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
parsed[ep.URL] = u
|
||||
}
|
||||
@@ -73,6 +80,10 @@ func Transport(endpoints []Endpoint, opts ...Option) (middleware.Middleware, *Cl
|
||||
|
||||
return func(next http.RoundTripper) http.RoundTripper {
|
||||
return middleware.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
|
||||
if parseErr != nil {
|
||||
return nil, parseErr
|
||||
}
|
||||
|
||||
healthy := endpoints
|
||||
if o.healthChecker != nil {
|
||||
healthy = o.healthChecker.Healthy(endpoints)
|
||||
|
||||
Reference in New Issue
Block a user