mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
fix(stockbit): end a browser sign-in on a CDN block
A block (UPSTREAMBLOCKED) was treated as a passing failure, so idx's browser re-checked the same cookie every 5 s until the 15-minute timeout, warning "does not retry a block ... retrying". A block holds for every session from this network: the wait now ends with it at once. Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
parent
362d314118
commit
9590219977
2 changed files with 41 additions and 5 deletions
|
|
@ -271,6 +271,12 @@ fn wait_for_session(
|
||||||
));
|
));
|
||||||
retry_at = Some(Instant::now() + VERIFY_RETRY);
|
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) => {
|
Err(err) => {
|
||||||
crate::runtime::warn(format!(
|
crate::runtime::warn(format!(
|
||||||
"Stockbit refused the session in idx's browser ({err}); sign in \
|
"Stockbit refused the session in idx's browser ({err}); sign in \
|
||||||
|
|
@ -1041,6 +1047,35 @@ mod tests {
|
||||||
let _ = std::fs::remove_dir_all(&profile);
|
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.
|
/// Closing the window ends the wait at once, not at the timeout.
|
||||||
#[test]
|
#[test]
|
||||||
fn closing_the_window_ends_the_wait() {
|
fn closing_the_window_ends_the_wait() {
|
||||||
|
|
|
||||||
|
|
@ -295,12 +295,10 @@ fn keep_after_failed_check(err: &IdxError, rotated: bool) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a session check failed for a reason that says nothing about the
|
/// 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 {
|
pub(crate) fn check_is_transient(err: &IdxError) -> bool {
|
||||||
matches!(
|
matches!(err, IdxError::Http(_) | IdxError::RateLimited)
|
||||||
err,
|
|
||||||
IdxError::Http(_) | IdxError::RateLimited | IdxError::UpstreamBlocked(_)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore(store: &SessionStore, previous: Option<Vec<u8>>) {
|
fn restore(store: &SessionStore, previous: Option<Vec<u8>>) {
|
||||||
|
|
@ -343,6 +341,9 @@ mod tests {
|
||||||
assert!(check_is_transient(&IdxError::RateLimited));
|
assert!(check_is_transient(&IdxError::RateLimited));
|
||||||
assert!(check_is_transient(&network));
|
assert!(check_is_transient(&network));
|
||||||
assert!(!check_is_transient(&refused));
|
assert!(!check_is_transient(&refused));
|
||||||
|
assert!(!check_is_transient(&IdxError::UpstreamBlocked(
|
||||||
|
"403".to_string()
|
||||||
|
)));
|
||||||
assert!(!check_is_transient(&IdxError::InvalidInput(
|
assert!(!check_is_transient(&IdxError::InvalidInput(
|
||||||
"x".to_string()
|
"x".to_string()
|
||||||
)));
|
)));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue