From a8b66be5d3cdedaf43150bd65395a885adc31964 Mon Sep 17 00:00:00 2001 From: Christoph Herzog Date: Mon, 14 Aug 2023 14:21:44 +0200 Subject: [PATCH] fix(cli): Prevent panics in "wasmer login" after API failures Previously login_and_save_token() was called from an async context. Since the function uses a blocking reqwest client for the internal GraphQL query, this could lead to panics when the API query failed, due to the blocking reqwest tokio runtime trying to shut down inside another tokio runtime, which is not allowed. This is fixed by running login_and_save_token() inside a spawned thread. Closes #4147 --- lib/cli/src/commands/login.rs | 36 ++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/cli/src/commands/login.rs b/lib/cli/src/commands/login.rs index e5d897c574a..d89b8289ddd 100644 --- a/lib/cli/src/commands/login.rs +++ b/lib/cli/src/commands/login.rs @@ -290,11 +290,21 @@ impl Login { match auth_state { AuthorizationState::TokenSuccess(token) => { - match wasmer_registry::login::login_and_save_token( - env.dir(), - registry.as_str(), - &token, - )? { + let res = std::thread::spawn({ + let dir = env.dir().to_owned(); + let registry = registry.clone(); + move || { + wasmer_registry::login::login_and_save_token( + &dir, + registry.as_str(), + &token, + ) + } + }) + .join() + .map_err(|err| anyhow::format_err!("handler thread died: {err:?}"))??; + + match res { Some(s) => { print!("Done!"); println!("\n✅ Login for Wasmer user {:?} saved", s) @@ -515,4 +525,20 @@ mod tests { .to_string(); assert_eq!(wasmer_env_token_help, login_token_help); } + + /// Regression test for panics on API errors. + /// See https://github.com/wasmerio/wasmer/issues/4147. + #[test] + fn login_with_invalid_token_does_not_panic() { + let cmd = Login { + no_browser: true, + wasmer_dir: WASMER_DIR.clone(), + registry: Some("http://localhost:11".to_string().into()), + token: Some("invalid".to_string()), + cache_dir: None, + }; + + let res = cmd.execute(); + assert!(res.is_err()); + } }