Documentation
¶
Overview ¶
Package failure holds the rendering the SDK's two failure taxonomies share.
The client's CallError and the content tier's FetchError are deliberately separate types over separate vocabularies — the content tier knows nothing about RPCs, and only one of them can decline to send. What is NOT deliberate is that they rendered themselves with byte-identical code, down to the reason a status with no name prints bare. One copy is what stops the two drifting into answering differently for the same failure.
Internal on purpose: error prose is not a protocol concept and has no cross-language counterpart to mirror.
Index ¶
- func Name[K comparable](names map[K]string, k K) string
- func ReasonOr(reason, kind string) string
- func RefusalHeader(status int, h http.Header) http.Header
- func RefuseRedirect(prefix, why string, redact func(string) string) func(*http.Request, []*http.Request) error
- func Render(prefix, op, kind string, status int, reason string, cause error) string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Name ¶
func Name[K comparable](names map[K]string, k K) string
Name renders a classification constant, falling back to "unknown" for a value outside the set. Both taxonomies are integer enums with a name map, and both must answer for a value they do not know rather than print a number.
func ReasonOr ¶
ReasonOr returns the peer's own token when it sent one, otherwise the failure class the SDK assigned. The most specific machine-readable answer available, which is what a caller branching on a reason wants.
func RefusalHeader ¶ added in v1.2.0
RefusalHeader returns the header fields a failure carries for the answer that produced it: a copy of h when the peer answered with an error status, 400 or above, and nil otherwise.
The rule has one owner because every leg must apply it identically, and the cases it leaves out are deliberate. A redirect carries none: its Location names a URL the peer chose, credentials included, and the error that refuses it already withholds that target, so the fields must not hand it back. A 2xx the client could not read is not a refusal, and a failure where no answer arrived has no fields to carry.
The copy is the caller's to keep, since the response the fields came from is closed before the error surfaces. The values are the peer's: unvalidated, bounded only by the HTTP client's own header limit, and never rendered into an error message.
func RefuseRedirect ¶
func RefuseRedirect(prefix, why string, redact func(string) string) func(*http.Request, []*http.Request) error
RefuseRedirect builds the http.Client CheckRedirect both credentialed legs install: neither an RPC nor a bound fetch is ever legitimately redirected, and following one would re-sign for a target the peer chose.
prefix names the tier and why names what may not be redirected, because the two legs decline for different reasons and a caller should read the right one. What is shared is the part that must NOT drift: the target is redacted rather than passed through url.URL.Redacted(), which masks userinfo passwords only and would render an attacker-chosen query into a log.
func Render ¶
Render builds the message both failure types print.
prefix names the tier that failed (the packages differ, and a reader should be able to tell from the first word which one produced this); op names what was being attempted; kind is the failure class's own token. Status, reason and cause are each appended only when present, so a bare classification renders as a bare classification rather than as a string of empty parentheses.
Types ¶
This section is empty.