Something went wrong. Try again.
sloproxy
Something went wrong. Try again.
4.1 kB · 173 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174package auth
import ( "encoding/json" "fmt" "strings")
// ErrorCodeRequestScoped identifies failures tied to the current request rather// than the selected credential.const ErrorCodeRequestScoped = "request_scoped"
const requestScopedErrorCode = ErrorCodeRequestScoped
// ErrorCodeConnectionLifecycle marks transport/session lifecycle failures that// must skip credential cooldown without being treated as request-scoped faults.const ErrorCodeConnectionLifecycle = "connection_lifecycle"
const connectionLifecycleErrorCode = ErrorCodeConnectionLifecycle
// ErrorCodeForceCooldown marks failures that must enforce credential cooldown.const ErrorCodeForceCooldown = "force_cooldown"
// Error describes an authentication related failure in a provider agnostic format.type Error struct { // Code is a short machine readable identifier. Code string `json:"code,omitempty"` // Message is a human readable description of the failure. Message string `json:"message"` // Retryable indicates whether a retry might fix the issue automatically. Retryable bool `json:"retryable"` // HTTPStatus optionally records an HTTP-like status code for the error. HTTPStatus int `json:"http_status,omitempty"`}
// Error implements the error interface.func (e *Error) Error() string { if e == nil { return "" } if e.Code == "" { return e.Message } return e.Code + ": " + e.Message}
// StatusCode implements optional status accessor for manager decision making.func (e *Error) StatusCode() int { if e == nil { return 0 } return e.HTTPStatus}
// IsRequestScoped reports whether the failure is tied to the current request// rather than the selected credential.func (e *Error) IsRequestScoped() bool { return e != nil && e.Code == ErrorCodeRequestScoped}
// MarkRequestScoped marks the error as request-scoped in place and returns it.func (e *Error) MarkRequestScoped() *Error { if e != nil { e.Code = ErrorCodeRequestScoped } return e}
// NewRequestScopedError creates an Error explicitly flagged as request-scoped so// that credential cooldown is skipped.func NewRequestScopedError(message string, httpStatus int) *Error { return &Error{ Code: ErrorCodeRequestScoped, Message: message, HTTPStatus: httpStatus, }}
type errorWithCause struct { base *Error cause error}
func (e *errorWithCause) Error() string { if e == nil || e.base == nil { return "" } baseText := e.base.Error() if e.cause == nil { return baseText } summary := ExtractUpstreamErrorSummary(e.cause.Error()) if summary != "" && !strings.Contains(baseText, summary) { return fmt.Sprintf("%s (last upstream error: %s)", baseText, summary) } return baseText}
func (e *errorWithCause) Unwrap() error { if e == nil { return nil } return e.cause}
func (e *errorWithCause) As(target any) bool { if e == nil { return false } if t, ok := target.(**Error); ok { *t = e.base return true } return false}
func (e *errorWithCause) Is(target error) bool { if e == nil { return target == nil } if target == e || target == e.base { return true } if other, ok := target.(*errorWithCause); ok && other != nil { return e.base == other.base } if otherErr, ok := target.(*Error); ok && otherErr != nil { return e.base == otherErr } return false}
func (e *errorWithCause) StatusCode() int { if e == nil || e.base == nil { return 0 } return e.base.HTTPStatus}
func (e *errorWithCause) IsRequestScoped() bool { if e == nil || e.base == nil { return false } return e.base.IsRequestScoped()}
func (e *errorWithCause) MarkRequestScoped() *Error { if e == nil || e.base == nil { return nil } return e.base.MarkRequestScoped()}
func (e *errorWithCause) MarshalJSON() ([]byte, error) { if e == nil || e.base == nil { return []byte("null"), nil } return json.Marshal(e.base)}
// WithCause wraps an *Error with an underlying cause without changing the Error struct layout.func WithCause(err *Error, cause error) error { if err == nil { return nil } if cause == nil { return err } return &errorWithCause{ base: err, cause: cause, }}