You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:25:34