#[non_exhaustive]pub enum IbkrFlexError {
EnvVar(String),
InvalidCredential(String),
Http(Error),
HttpStatus {
status: u16,
body: String,
},
Flex {
code: String,
message: String,
},
PollTimeout {
attempts: u32,
},
Parse(String),
}Expand description
Errors from IBKR Flex Web Service operations.
#[non_exhaustive]: the Flex service may introduce new failure conditions over time, so new
variants can be added without a breaking change; downstream matches must include a wildcard arm.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
EnvVar(String)
A required environment variable is not set (see IbkrFlexConfig::from_env).
InvalidCredential(String)
A supplied credential (the Flex token or query_id) is empty after trimming surrounding
whitespace. Raised by IbkrFlexConfig::new so a malformed credential fails observably at
construction, naming the offending field, rather than later as an opaque IBKR 1003
“invalid token” after a live fetch.
Http(Error)
Transport-level HTTP error (connection, timeout, or body-decode failure).
A non-2xx HTTP status no longer surfaces here: the client reads the response body before
branching on status and reports a non-success status as IbkrFlexError::HttpStatus (or the
richer IbkrFlexError::Flex when the body is a Flex error envelope). This variant is now
purely a connection/timeout/decode failure.
The inner reqwest::Error never carries the request URL. The Flex token is
transmitted as t=<TOKEN> in every request URL, and reqwest::Error’s Display and
Debug both embed that URL verbatim when present. The From<reqwest::Error> conversion
for this type always strips it via reqwest::Error::without_url before the error is
stored, covering every reqwest site that attaches a URL (send, body decode);
Client::build() errors carry no URL, so the strip is a no-op for them. The source()
chain (hyper/IO transport errors) is preserved and does not independently carry the URL.
Safe to log or display without credential scrubbing.
HttpStatus
The service returned a non-success HTTP status whose body was not a recognizable Flex envelope — e.g. a proxy/CDN/WAF error page or a gateway timeout served in front of the Flex Web Service.
The body is read before the status is inspected (so the diagnostic is preserved rather than
discarded by error_for_status), then bounded to 1 KiB and
token-scrubbed before storage: the Flex token rides in the request URL’s t= parameter,
so a proxy that echoes the request line into its error page could otherwise reflect the
credential into this body. The scrub is best-effort defense-in-depth — it redacts both the
raw token and the encoded form it takes on the wire. An IBKR
application error that arrives under a non-2xx status is still surfaced as the richer
IbkrFlexError::Flex, not here.
Fields
Flex
The Flex service returned a non-success status (e.g. invalid token, throttled, expired).
message is the <ErrorMessage> element lifted from a server-supplied body, so — like
IbkrFlexError::HttpStatus and IbkrFlexError::Parse — both fields are bounded to 1 KiB
and token-scrubbed before storage: a proxy that reflected the request line into its
<ErrorMessage> could otherwise carry the t= Flex token into it. The scrub is a no-op for a
real numeric Flex code/message that does not contain the token.
Fields
PollTimeout
The statement was still generating after the configured poll budget was exhausted.
Fields
attempts: u32Number of poll attempts made before giving up — the configured
FlexPollPolicy::max_attempts (12 by default), since this error
fires only after every attempt reported the statement still generating.
Parse(String)
The statement or status XML could not be parsed.
A parse message embeds the deserialiser’s own rendering of the offending input, so its
length tracks the document rather than the failure, and a document that reflected the
request line could carry the t= credential into it. This variant is therefore always
bounded to 1 KiB, and token-scrubbed on every path where a token is in scope — the
same protection IbkrFlexError::HttpStatus gets, for the same reason.
Scrubbing covers every Parse returned by IbkrFlexClient::fetch_statement_xml and
IbkrFlexClient::fetch_corporate_actions. The one path it cannot cover is calling
parse_corporate_actions directly: there the caller supplies its own XML and no token
exists to redact. Such a message is still bounded — just not scrubbed, since there is
nothing to scrub against.
Trait Implementations§
Source§impl Debug for IbkrFlexError
impl Debug for IbkrFlexError
Source§impl Display for IbkrFlexError
impl Display for IbkrFlexError
Source§impl Error for IbkrFlexError
impl Error for IbkrFlexError
1.30.0 · 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()
Source§impl From<Error> for IbkrFlexError
Convert a reqwest::Error into IbkrFlexError::Http with its request URL stripped.
impl From<Error> for IbkrFlexError
Convert a reqwest::Error into IbkrFlexError::Http with its request URL stripped.
The Flex token rides in the t= query parameter (IBKR’s protocol), so it is part of every
request URL. reqwest::Error’s Display/Debug embed the stored URL verbatim — e.g.
"... for url (https://.../SendRequest?t=<TOKEN>&q=...)" — so an unstripped error would leak the
credential into any log that formats IbkrFlexError::Http (the shipped example does exactly
that).
Stripping lives in this single conversion rather than per-call-site discipline so the
“IbkrFlexError::Http never carries the URL” invariant is enforced by the type system: every
? on a reqwest::Error — at the request sites (send, body decode) and any path added later
— routes through here.
reqwest::Error::without_url sets the stored URL to None (a no-op for Client::build()
errors, which carry none) while preserving the diagnostic kind/status and source() chain.
Auto Trait Implementations§
impl !RefUnwindSafe for IbkrFlexError
impl !UnwindSafe for IbkrFlexError
impl Freeze for IbkrFlexError
impl Send for IbkrFlexError
impl Sync for IbkrFlexError
impl Unpin for IbkrFlexError
impl UnsafeUnpin for IbkrFlexError
Blanket Implementations§
Source§impl<T> AttachedTransformer<()> for T
impl<T> AttachedTransformer<()> for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> JsonSchemaMaybe for T
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.