Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions pkg/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@ var ErrCurrencyNotAccepted = errors.New("currency not accepted")
// contract until the platform persists a typed flag (platform #778).
var ErrOutcomeUnknown = errors.New("purchase outcome unknown")

// ErrRefusedBeforePurchase wraps any error from the approved-upfront check or
// the purchase-count bounds check, both of which run before the purchase
// request is built or sent. Its presence is
// sufficient to know that this call sent no purchase request, but its absence
// proves nothing: other refusals do not carry it. It describes only the call
// that returned it and says nothing about earlier calls with the same
// ErrRefusedBeforePurchase wraps an error from a check that refused the
// purchase before the purchase request was built or sent. It says nothing
// about why: the cause may be an offering upfront above the approved amount
// (or one that cannot be compared with it), a count bound, a service-ownership
// rule, or a duplicate-purchase guard, and retrying or asking for approval may
// not help. Some producers wrap only the sentinel and carry the cause in the
// message, so callers cannot rely on unwrapping to tell the causes apart. Its
// presence is sufficient to know that this call sent no purchase request, but
// its absence proves nothing: other refusals do not carry it. It describes only
// the call that returned it and says nothing about earlier calls with the same
// idempotency token. A wrapper that combines several purchase calls must not
// propagate it unless none of them sent a request. Detect it with
// errors.Is(err, ErrRefusedBeforePurchase).
Expand Down
Loading