Files
httpx/error.go
Aleksey Shakhmatov 5cfd1a7400 Fix sentinel error aliasing, hot-path allocations, and resource leaks
- Deduplicate sentinel errors: httpx.ErrNoHealthy, ErrCircuitOpen, and
  ErrRetryExhausted are now aliases to the canonical sub-package values
  so errors.Is works across package boundaries
- Retry transport returns ErrRetryExhausted only when all attempts are
  actually exhausted, not on early policy exit
- Balancer: pre-parse endpoint URLs at construction, replace req.Clone
  with cheap shallow struct copy to avoid per-request allocations
- Circuit breaker: Load before LoadOrStore to avoid allocating a Breaker
  on every request for known hosts
- Health checker: drain response body before close for connection reuse,
  probe endpoints concurrently, run initial probe synchronously in Start
- Client: add Close() to shut down health checker goroutine, propagate
  URL resolution errors instead of silently discarding them
- MockClock: fix lock ordering in Reset (clock.mu before t.mu), fix
  timer slice compaction to avoid backing-array aliasing, extract
  fireExpired to deduplicate Advance/Set
2026-03-20 15:21:32 +03:00

50 lines
1.5 KiB
Go

package httpx
import (
"fmt"
"net/http"
"git.codelab.vc/pkg/httpx/balancer"
"git.codelab.vc/pkg/httpx/circuitbreaker"
"git.codelab.vc/pkg/httpx/retry"
)
// Sentinel errors returned by httpx components.
// These are aliases for the canonical errors defined in sub-packages,
// so that errors.Is works regardless of which import the caller uses.
var (
ErrRetryExhausted = retry.ErrRetryExhausted
ErrCircuitOpen = circuitbreaker.ErrCircuitOpen
ErrNoHealthy = balancer.ErrNoHealthy
)
// Error provides structured error information for failed HTTP operations.
type Error struct {
// Op is the operation that failed (e.g. "Get", "Do").
Op string
// URL is the originally-requested URL.
URL string
// Endpoint is the resolved endpoint URL (after balancing).
Endpoint string
// StatusCode is the HTTP status code, if a response was received.
StatusCode int
// Retries is the number of retry attempts made.
Retries int
// Err is the underlying error.
Err error
}
func (e *Error) Error() string {
if e.Endpoint != "" && e.Endpoint != e.URL {
return fmt.Sprintf("httpx: %s %s (endpoint %s): %v", e.Op, e.URL, e.Endpoint, e.Err)
}
return fmt.Sprintf("httpx: %s %s: %v", e.Op, e.URL, e.Err)
}
func (e *Error) Unwrap() error { return e.Err }
// ErrorMapper maps an HTTP response to an error. If the response is
// acceptable, the mapper should return nil. Used by Client to convert
// non-successful HTTP responses into Go errors.
type ErrorMapper func(resp *http.Response) error