Build a retry queue that respects Retry-After and action identity
Schedule bounded retries from structured errors and HTTP delay hints without creating a burst of replacement actions.
Create a failure model that preserves uncertainty and distinguishes invalid requests, admission decisions and incomplete external effects.
A network client can observe a connection failure, an HTTP response or a response body it cannot parse. A business workflow needs different information: whether the requested action was rejected, accepted, completed or remains unknown. Compressing both layers into ok: false discards the evidence needed to recover safely.
Use a small typed outcome model that carries transport status, structured API code, operation identity and known execution phase separately. Keep the original response in private bounded diagnostics when needed, but give ordinary application code a stable classification rather than requiring it to match a full human-readable error message.
Validation failures need corrected input. Authentication failures need a valid credential. A missing permission needs an authorized access decision. Lupin’s error reference describes these as distinct categories, with protected resources sometimes deliberately appearing absent. A client should not repeatedly retry them just because an operation has not succeeded.
Request repair may create a different logical action. If a side effect was already dispatched, first establish its outcome before sending the corrected version. The presence of a new syntactically valid payload does not prove that the earlier request failed before execution.
Budget, allowance, payment readiness and resource capacity gates can reject an otherwise valid action. These are local policy decisions with their own repair paths. A provider outage dashboard is unlikely to explain them, and a fallback provider must not become an automatic route around the same authorization or spending boundary.
Record whether the rejection was durably saved. Lupin’s paid operation journals use that distinction to make replay reliable. An error while persisting admission can leave a reservation uncertain even when no new provider call began, so classify its recovery requirement independently from ordinary provider acceptance.
A timeout or connection loss after dispatch can leave the provider outcome unknown. Preserve this as its own state rather than equating it with rejection. The queue can permit reads and reconciliation while blocking replacement effects. This is especially important when an action has financial or communication consequences.
An HTTP success also needs interpretation. It may describe creation of a resource, acceptance of asynchronous work or a completed read. Inspect the endpoint’s response contract and resource status before reporting business completion. Neither the HTTP client nor the model should invent a stronger outcome than the returned evidence supports.
For each failure category, document who can repair it, whether the original identity is retained, which reads are safe and what evidence closes the case. Include a separate escalation path for unavailable durable storage because the system may be unable to prove either final rejection or successful recovery.
Exercise the table with local fixtures that return invalid JSON, structured permission denial, a rate limit, an admission rejection and an accepted action whose response is lost. The classifier should produce different workflow decisions for those cases. Test the resulting decisions, not only whether the client throws an exception.
Reviewed against the checked-in Lupin implementation and official reference documentation on 2026-11-05. Operational examples are illustrative; no live paid action, provider mutation or external message was executed.
Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.