pub enum ClientError {
Http(Error),
Unauthorized {
message: String,
},
RateLimited {
retry_after: Option<Duration>,
},
RetryableServer {
status: u16,
message: String,
},
Api(String),
Serde(Error),
}Expand description
A typed failure from an StClient call: transport errors,
401/429/5xx HTTP classes, deserialization failures, and other game/API
errors. Use ClientError::is_retryable / ClientError::is_unauthorized
to branch on transient vs. terminal outcomes.
use spacetraders_client::ClientError;
let err = ClientError::RateLimited { retry_after: None };
assert!(err.is_retryable());
assert!(!err.is_unauthorized());Variants§
Http(Error)
Transport/communication failure (connection reset, timeout, DNS, …). Transient: the engine should back off and retry rather than crash.
401: the agent token is no longer valid, typically after a server reset.
Run-control keeps this on a dedicated path (notify FleetCommander).
Fields
RateLimited
429: rate limited. retry_after carries the server’s Retry-After hint
when present. Transient.
RetryableServer
5xx: server-side / maintenance failure. Transient.
Api(String)
A non-retryable game/API error: bad state, invalid action, insufficient funds, 404, and any other status we do not special-case.
Serde(Error)
Implementations§
Source§impl ClientError
impl ClientError
Sourcepub fn is_retryable(&self) -> bool
pub fn is_retryable(&self) -> bool
Whether the failure is transient and worth retrying automatically:
communication errors, 429 rate limits, and 5xx server errors. This is the
idempotent-read view; mutations must go through Self::is_retryable_under.
Sourcepub fn is_retryable_under(&self, policy: RetryPolicy) -> bool
pub fn is_retryable_under(&self, policy: RetryPolicy) -> bool
Whether this error is safe to retry automatically under policy.
For RetryPolicy::Idempotent this is exactly Self::is_retryable.
For RetryPolicy::Mutating only a 429 qualifies: the rate limiter
rejects it before the mutation runs, so no change was applied. A 5xx or
communication error is ambiguous — the server may have applied the
change — so a non-idempotent request must not be replayed.
Sourcepub fn is_ambiguous_mutation(&self) -> bool
pub fn is_ambiguous_mutation(&self) -> bool
Whether a failed mutation left the outcome ambiguous: the request may have reached the game and applied server-side even though the client saw an error. True for 5xx and communication failures (the response was lost or the server faulted mid-write); false for a 429 (rejected before the action ran) and for deterministic game errors (e.g. insufficient funds), where the prior state is known to still hold. Callers use this to decide whether to re-read authoritative state before acting again.
Sourcepub fn retry_after(&self) -> Option<Duration>
pub fn retry_after(&self) -> Option<Duration>
Server-suggested delay before retrying, when one was provided (the
Retry-After header on a 429).
pub fn class(&self) -> &'static str
Trait Implementations§
Source§impl Debug for ClientError
impl Debug for ClientError
Source§impl Display for ClientError
impl Display for ClientError
Source§impl Error for ClientError
impl Error for ClientError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()