middleware

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package middleware composes auth, retry, and RFC 7807 error mapping for the PayAgentic HTTP transport.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateIdempotencyKey

func GenerateIdempotencyKey() string

GenerateIdempotencyKey returns a fresh UUID v4 string suitable for Idempotency-Key headers on non-idempotent (POST/PUT/PATCH/DELETE) requests.

func IsConflict

func IsConflict(err error) bool

IsConflict reports whether the error is a 409 Conflict.

func IsForbidden

func IsForbidden(err error) bool

IsForbidden reports whether the error is a 403 Forbidden.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether the error is a 404 Not Found.

func IsRateLimit

func IsRateLimit(err error) bool

IsRateLimit reports whether the error is a 429 Too Many Requests.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable reports whether the given error represents a transient failure that should be retried.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized reports whether the error is a 401 Unauthorized.

func IsValidation

func IsValidation(err error) bool

IsValidation reports whether the error is a 422 Unprocessable Entity.

func NewAuthTransport

func NewAuthTransport(opts AuthOptions) http.RoundTripper

NewAuthTransport returns a RoundTripper that authenticates outgoing requests with the configured API key and adds an Idempotency-Key (UUID v4) on POST/PUT/PATCH/DELETE unless the caller supplied one.

func NewProblemDetailsTransport

func NewProblemDetailsTransport(inner http.RoundTripper) http.RoundTripper

NewProblemDetailsTransport returns a RoundTripper that, after the inner RT returns, reads non-2xx response bodies and returns the matching typed error (UnauthorizedError, RateLimitError, etc) via ParseErrorResponse.

2xx responses pass through with the body intact.

func NewTransport

func NewTransport(opts TransportOptions) http.RoundTripper

NewTransport returns a fully wired http.RoundTripper composing:

  1. authTransport — injects Authorization, X-Agent-ID, Idempotency-Key
  2. problemDetailsTransport — converts non-2xx to typed errors
  3. retryTransport — retries 5xx/429/network failures (sees raw status)
  4. (inner) http.DefaultTransport — the actual network

retryTransport sits innermost (below problem-details) so it inspects raw HTTP status codes via isRetryableStatus rather than typed errors; this avoids retrying 401/403/422 and only retries 408/429/502/503/504.

Drop this into &http.Client{Transport: NewTransport(...)} and the resulting Client behaves like a vanilla http.Client but with all PayAgentic SDK invariants honoured.

func ParseErrorResponse

func ParseErrorResponse(statusCode int, body []byte, traceID string) error

ParseErrorResponse constructs the appropriate typed error from an HTTP response.

func WithRetry

func WithRetry(ctx context.Context, policy RetryPolicy, fn func() (*http.Response, error)) (*http.Response, error)

WithRetry executes fn with retries according to the given policy. Only responses with retryable HTTP status codes trigger a retry.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status code returned by the API.
	StatusCode int
	// Problem contains the structured error details (RFC 9457).
	Problem ProblemDetails
	// TraceID is the trace identifier for correlating with server logs.
	TraceID string
}

APIError represents an API error response from PayAgentic.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

type AuthOptions

type AuthOptions struct {
	// APIKey is sent as `Authorization: Bearer <APIKey>` on every request.
	APIKey string
	// AgentID, when non-empty, is sent as `X-Agent-ID: <AgentID>`.
	AgentID string
	// Inner is the wrapped RoundTripper. Defaults to http.DefaultTransport.
	Inner http.RoundTripper
}

AuthOptions configures NewAuthTransport.

type ConflictError

type ConflictError struct{ *APIError }

ConflictError is returned on resource conflicts (HTTP 409).

type ForbiddenError

type ForbiddenError struct{ *APIError }

ForbiddenError is returned when authorization fails (HTTP 403).

type NotFoundError

type NotFoundError struct{ *APIError }

NotFoundError is returned when a resource is not found (HTTP 404).

type ProblemDetails

type ProblemDetails struct {
	Type     string `json:"type,omitempty"`
	Title    string `json:"title,omitempty"`
	Status   int    `json:"status,omitempty"`
	Detail   string `json:"detail,omitempty"`
	Instance string `json:"instance,omitempty"`
}

ProblemDetails follows RFC 9457 for structured error responses.

type RateLimitError

type RateLimitError struct{ *APIError }

RateLimitError is returned when the rate limit is exceeded (HTTP 429).

type RetryPolicy

type RetryPolicy struct {
	// MaxRetries is the maximum number of retry attempts (0 means no retries).
	MaxRetries int
	// BaseDelay is the initial backoff delay.
	BaseDelay time.Duration
	// MaxDelay is the upper bound on backoff delay.
	MaxDelay time.Duration
	// Jitter enables randomised delay to avoid thundering herds.
	Jitter bool
}

RetryPolicy configures the retry behaviour for transient failures.

func DefaultRetryPolicy

func DefaultRetryPolicy() RetryPolicy

DefaultRetryPolicy returns a sensible default retry policy.

type TransportOptions

type TransportOptions struct {
	// APIKey is the bearer token sent on every request.
	APIKey string
	// AgentID, when non-empty, is sent as X-Agent-ID.
	AgentID string
	// RetryPolicy controls retry behaviour. Zero value uses DefaultRetryPolicy().
	RetryPolicy RetryPolicy
	// Inner is the wrapped RoundTripper. Defaults to http.DefaultTransport.
	Inner http.RoundTripper
}

TransportOptions configures NewTransport.

type UnauthorizedError

type UnauthorizedError struct{ *APIError }

UnauthorizedError is returned when authentication fails (HTTP 401).

type ValidationError

type ValidationError struct{ *APIError }

ValidationError is returned on invalid input (HTTP 422).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL