51 lines
1.1 KiB
Go
51 lines
1.1 KiB
Go
package merrors
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// ThrottleDetails describes a temporary request limit without coupling callers
|
|
// to a transport-specific response format.
|
|
type ThrottleDetails struct {
|
|
ScopeKind string
|
|
RetryAfter time.Duration
|
|
}
|
|
|
|
type throttleDetailsError struct {
|
|
base error
|
|
msg string
|
|
details ThrottleDetails
|
|
}
|
|
|
|
func (e throttleDetailsError) Error() string {
|
|
return Wrap(e.base, e.msg).Error()
|
|
}
|
|
|
|
func (e throttleDetailsError) Unwrap() error {
|
|
return e.base
|
|
}
|
|
|
|
// WithThrottle annotates an error with retry information while preserving its
|
|
// classification for errors.Is and errors.As.
|
|
func WithThrottle(base error, scopeKind string, retryAfter time.Duration, msg string) error {
|
|
return throttleDetailsError{
|
|
base: base,
|
|
msg: msg,
|
|
details: ThrottleDetails{
|
|
ScopeKind: strings.TrimSpace(scopeKind),
|
|
RetryAfter: retryAfter,
|
|
},
|
|
}
|
|
}
|
|
|
|
// ThrottleDetailsFrom returns retry information attached by WithThrottle.
|
|
func ThrottleDetailsFrom(err error) (ThrottleDetails, bool) {
|
|
var throttled throttleDetailsError
|
|
if !errors.As(err, &throttled) {
|
|
return ThrottleDetails{}, false
|
|
}
|
|
return throttled.details, true
|
|
}
|