pub enum Error {
Unauthorized(ErrorBody),
NotFound(ErrorBody),
RateLimited {
retry_after: Option<Duration>,
body: ErrorBody,
},
Http {
status: StatusCode,
retry_after: Option<Duration>,
body: ErrorBody,
},
Transport(Error),
WebSocket(WebSocketError),
Codec {
context: String,
reason: String,
},
InvalidPreference {
field: &'static str,
reason: String,
},
OrderIdUnrecoverable(String),
OrderResponseNotRepresentable {
reason: String,
},
TokenProvider {
source: Box<dyn Error + Send + Sync>,
},
InsecureBaseUrl {
url: String,
reason: String,
},
}Expand description
Error returned by every fallible operation in this crate.
Variants§
HTTP 401. Distinct from Error::Http so a future token-refresh
seam in SchwabClient has a single arm to hook.
NotFound(ErrorBody)
HTTP 404. Distinct from Error::Http because callers idiomatically
map “broker says no such resource” to Ok(None).
RateLimited
429 with optional Retry-After.
Fields
Http
Any other non-2xx response. The status is authoritative; the body
is supplementary. retry_after carries the parsed Retry-After
header when the server sent one (the spec allows it on any 4xx /
5xx, not only 429); callers can read it via
Error::retry_after without matching on the variant.
Fields
status: StatusCodeHTTP status from the response.
Transport(Error)
reqwest transport failure (DNS, connect, TLS, body read).
WebSocket(WebSocketError)
Streamer websocket: connect, handshake, or runtime frame error.
Codec
JSON serde failure on a wire body or streamer frame. context
names the operation (e.g. "decode CHART_EQUITY frame",
"encode subscribe request").
Fields
InvalidPreference
/userPreference response missing a required field or carrying
an unparseable value.
Fields
OrderIdUnrecoverable(String)
Schwab acked a place / replace order but the Location header
was absent or malformed, so the new order’s id is unrecoverable.
OrderResponseNotRepresentable
An crate::orders::Order returned by a read endpoint could not
be converted into an crate::orders::OrderRequest for a
follow-up place or replace call. The carried reason names the
specific shape mismatch (e.g. a leg missing its instrument, an
instrument missing its symbol, an unknown assetType). This
variant is not retryable: the response will not change on a retry.
TokenProvider
A crate::TokenProvider failed to produce a bearer token, so no
HTTP request could be issued. The wrapped source is the
provider’s own error type, type-erased; the SDK has no opinion on
whether it is transient.
InsecureBaseUrl
A base URL passed to crate::SchwabClient::with_trader_base_url
or crate::SchwabClient::with_market_data_base_url used a
scheme that is not permitted for the current build. Release
builds require https://; debug builds additionally permit
http:// so local fixture servers (wiremock and similar) can be
wired up in tests.
Implementations§
Source§impl Error
impl Error
Sourcepub fn is_retryable(&self) -> bool
pub fn is_retryable(&self) -> bool
Schwab-specific retry classification. Returns true for transient
failures (network, 5xx, 429) where the same request can be safely
retried by the caller. Returns false for terminal failures
(4xx other than 429, codec errors, preference / location errors).
schwab-sdk does not implement retry itself; this method exists
so downstream consumers can utilize it in their own retry logic.
§Examples
A minimal backoff loop honoring Self::retry_after when present.
In real code a crate such as backon is preferable; this shows the
seam.
use std::time::Duration;
use schwab_sdk::Result;
async fn with_retry<F, Fut, T>(mut op: F) -> Result<T>
where
F: FnMut() -> Fut,
Fut: std::future::Future<Output = Result<T>>,
{
let mut attempts = 0;
loop {
match op().await {
Ok(value) => return Ok(value),
Err(err) if err.is_retryable() && attempts < 3 => {
attempts += 1;
let delay = err.retry_after().unwrap_or(Duration::from_millis(500));
tokio::time::sleep(delay).await;
}
Err(err) => return Err(err),
}
}
}
let quotes = with_retry(|| client.market_data().quotes().list(["AAPL"]).send()).await?;Sourcepub fn retry_after(&self) -> Option<Duration>
pub fn retry_after(&self) -> Option<Duration>
Retry-After duration parsed from a non-2xx response, when the
server sent the header. None for variants that do not carry
HTTP status (transport, codec, etc.) or when the header was
absent. Surfaces on both Error::RateLimited (429) and
Error::Http (any other 4xx / 5xx Schwab annotated with
Retry-After, typically 503).
Trait Implementations§
Source§impl Error for Error
impl Error for Error
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()