Tauri应用中tournament_search命令无法被invoke调用且无报错
问题描述
前端调用3个Tauri命令时,set_api_key和check_connection运行正常,但tournament_search命令无法被调用。已排查零宽字符、JS事件触发情况,确认问题仅为该函数未被执行。
相关代码如下:
main.rs
fn main() { tauri::Builder::default() .manage(ApiKey {key: Default::default()}) .invoke_handler(tauri::generate_handler![set_api_key, check_connection, tournament_search]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } #[tauri::command] fn set_api_key(key: String , state: State<ApiKey>){ let mut api_key = state.key.lock().unwrap(); *api_key = key; } #[tauri::command] async fn check_connection(api_key: State<'_, ApiKey>) -> Result<bool, ()> { let key = api_key.key.lock().unwrap().clone(); let res = Client::new().get(API_URL).bearer_auth(key).send().await.unwrap().text().await.unwrap(); let json: Value = serde_json::from_str(res.as_str()).unwrap(); match json["success"].as_bool() { Some(_x) => Ok(false), None => Ok(true) } } #[tauri::command] async fn tournament_search(search_string: String, api_key: State<'_, ApiKey>) -> Result<&str, ()> { println!("test: {}", search_string); let key = api_key.key.lock().unwrap().clone(); let mut query: String = String::new(); query.push_str("query($name:String){tournaments(query:{filter:{name:$name}}){nodes{name,slug,id}}},{$name:"); query.push_str(search_string.as_str()); query.push_str("}"); let res = Client::new().get(API_URL).bearer_auth(key).body(query).send().await.unwrap().text().await.unwrap(); println!("{}", res); Ok("") }
index.js
const { invoke } = window.__TAURI__.tauri window.addEventListener("load", (ev) => { let test = document.getElementById("test"); let apiKey = document.getElementById("apiKey"); let tournamentSearch = document.getElementById("tournamentSearch"); let tourneyList = document.getElementById("tourneyList"); apiKey.addEventListener("input", (ev) => { invoke("set_api_key", {key: apiKey.value}); invoke("check_connection").then((res) => { if(res){ tournamentSearch.disabled = false; }else{ tournamentSearch.disabled = true; } }); }); tournamentSearch.addEventListener("input", (ev) => { test.innerText = "e"; invoke('tournament_search', {search_string: tournamentSearch.value}).then((res) => { test.innerText = res; }); }); });
问题排查与解决方案
1. 修复命令返回值类型错误
tournament_search返回的Result<&str, ()>中,&str是引用类型,Tauri异步命令要求返回值为可序列化的拥有类型,引用类型会导致序列化失败,进而命令静默失效。
修改返回类型为Result<String, ()>:
#[tauri::command] async fn tournament_search(search_string: String, api_key: State<'_, ApiKey>) -> Result<String, ()> { println!("test: {}", search_string); let key = api_key.key.lock().unwrap().clone(); let mut query: String = String::new(); query.push_str("query($name:String){tournaments(query:{filter:{name:$name}}){nodes{name,slug,id}}},{$name:"); query.push_str(search_string.as_str()); query.push_str("}"); let res = Client::new().get(API_URL).bearer_auth(key).body(query).send().await.unwrap().text().await.unwrap(); println!("{}", res); Ok(String::from("")) }
2. 添加JS端错误捕获
在JS调用中增加错误处理,明确是否存在调用报错:
tournamentSearch.addEventListener("input", (ev) => { test.innerText = "e"; invoke('tournament_search', {search_string: tournamentSearch.value}) .then((res) => { test.innerText = res; }) .catch((err) => { console.error("tournament_search调用失败:", err); test.innerText = "调用失败: " + err.message; }); });
3. 替换panic风险的unwrap()
代码中大量使用unwrap(),若API请求、JSON解析失败会直接panic,导致命令无响应。建议替换为错误处理:
// 示例:替换unwrap为match分支处理 let res = match Client::new().get(API_URL).bearer_auth(key).body(query).send().await { Ok(resp) => resp, Err(_) => return Err(()), }; let res_text = match res.text().await { Ok(text) => text, Err(_) => return Err(()), };
4. 确保代码编译生效
重新编译并重启Tauri应用,避免热重载未同步代码变更的情况。
内容的提问来源于stack exchange,提问作者Xirom
相关产品推荐
相关产品推荐

