diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index bf900820f51719bf95c13bca591648da9a55c35c..a76393dfdb98bf3d73b6e4842d8da76c935a96a3 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -336,6 +336,7 @@ impl Credentials { } } +pub const CREDENTIAL_READ_TIMEOUT: Duration = Duration::from_secs(10); pub struct ClientCredentialsProvider { provider: Arc, } @@ -352,11 +353,15 @@ impl ClientCredentialsProvider { } /// Reads the credentials from the provider. + /// + /// Times out after [`CREDENTIAL_READ_TIMEOUT`] seconds returning None and + /// logging the timeout as error fn read_credentials<'a>( &'a self, cx: &'a AsyncApp, ) -> Pin> + 'a>> { async move { + let executor = cx.background_executor(); if IMPERSONATE_LOGIN.is_some() { return None; } @@ -365,7 +370,10 @@ impl ClientCredentialsProvider { let (user_id, access_token) = self .provider .read_credentials(&server_url, cx) + .with_timeout(CREDENTIAL_READ_TIMEOUT, executor) .await + .map_err(|_| anyhow!("Timed out waiting for credentials from OS")) + .flatten() .log_err() .flatten()?; @@ -883,7 +891,10 @@ impl Client { match self .credentials_provider .read_credentials(cx) - .with_timeout(Duration::from_secs(10), executor) + .with_timeout( + CREDENTIAL_READ_TIMEOUT - Duration::from_millis(200), + executor, + ) .await { Ok(None) => (), @@ -898,6 +909,8 @@ impl Client { } } Err(Timeout) => { + // Todo do not time out but show toast after 10s. Hide toast + // when keyring unlocks. return Err(anyhow!( "Timed out waiting for credentials from OS, did you unlock the keyring?" ));