mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 01:35:36 +00:00
Merge branch 'feat/stockbit-login' into feat/stockbit-corpaction
Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
commit
4b56f8c516
2 changed files with 41 additions and 5 deletions
|
|
@ -271,6 +271,12 @@ fn wait_for_session(
|
|||
));
|
||||
retry_at = Some(Instant::now() + VERIFY_RETRY);
|
||||
}
|
||||
// A block holds for every session from this network, so
|
||||
// the wait ends with it rather than at the timeout.
|
||||
Err(err @ IdxError::UpstreamBlocked(_)) => {
|
||||
devtools.close();
|
||||
return Err(err);
|
||||
}
|
||||
Err(err) => {
|
||||
crate::runtime::warn(format!(
|
||||
"Stockbit refused the session in idx's browser ({err}); sign in \
|
||||
|
|
@ -1041,6 +1047,35 @@ mod tests {
|
|||
let _ = std::fs::remove_dir_all(&profile);
|
||||
}
|
||||
|
||||
/// A CDN block is never retried: the wait ends with it at once, not at
|
||||
/// the timeout.
|
||||
#[test]
|
||||
fn a_blocked_check_ends_the_wait() {
|
||||
let profile = temp_dir("blocked");
|
||||
let browser = FakeBrowser::start(Fake::default());
|
||||
write_endpoint(&profile, browser.port);
|
||||
let mut devtools = connect(&profile, &|| true).unwrap();
|
||||
let checks = std::cell::Cell::new(0);
|
||||
let started = Instant::now();
|
||||
let err = wait_for_session(
|
||||
&mut devtools,
|
||||
Duration::from_secs(30),
|
||||
&|_| {
|
||||
checks.set(checks.get() + 1);
|
||||
Err(IdxError::UpstreamBlocked(
|
||||
"HTTP 403 from its CDN".to_string(),
|
||||
))
|
||||
},
|
||||
&|| true,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, IdxError::UpstreamBlocked(_)), "{err}");
|
||||
assert_eq!(checks.get(), 1);
|
||||
assert!(started.elapsed() < Duration::from_secs(5));
|
||||
browser.finish();
|
||||
let _ = std::fs::remove_dir_all(&profile);
|
||||
}
|
||||
|
||||
/// Closing the window ends the wait at once, not at the timeout.
|
||||
#[test]
|
||||
fn closing_the_window_ends_the_wait() {
|
||||
|
|
|
|||
|
|
@ -308,12 +308,10 @@ fn keep_after_failed_check(err: &IdxError, rotated: bool) -> bool {
|
|||
}
|
||||
|
||||
/// Whether a session check failed for a reason that says nothing about the
|
||||
/// session itself, so the same session may be checked again later.
|
||||
/// session itself, so the same session may be checked again later. A CDN
|
||||
/// block (`UpstreamBlocked`) is not: idx never retries a block.
|
||||
pub(crate) fn check_is_transient(err: &IdxError) -> bool {
|
||||
matches!(
|
||||
err,
|
||||
IdxError::Http(_) | IdxError::RateLimited | IdxError::UpstreamBlocked(_)
|
||||
)
|
||||
matches!(err, IdxError::Http(_) | IdxError::RateLimited)
|
||||
}
|
||||
|
||||
fn restore(store: &SessionStore, previous: Option<Vec<u8>>) {
|
||||
|
|
@ -356,6 +354,9 @@ mod tests {
|
|||
assert!(check_is_transient(&IdxError::RateLimited));
|
||||
assert!(check_is_transient(&network));
|
||||
assert!(!check_is_transient(&refused));
|
||||
assert!(!check_is_transient(&IdxError::UpstreamBlocked(
|
||||
"403".to_string()
|
||||
)));
|
||||
assert!(!check_is_transient(&IdxError::InvalidInput(
|
||||
"x".to_string()
|
||||
)));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue