Tauri で invalid args hogeHoge for command func: command func missing required key hogeHoge のエラーが出力される

経緯

Tauri で React 側の入力値を Rust に渡す際に以下のエラーが出力される事象に遭遇したのでメモ。

Uncaught (in promise) invalid args hogeHoge for command func: command func missing required key hogeHoge

もう少し正確に書くと以下のエラーとなります。

Uncaught (in promise) invalid args hogeHoge for command greet: command greet missing required key hogeHoge

コード

事象が発生した際のコードは以下のような感じです。

React (App.tsx)

import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
import 'bootstrap/dist/css/bootstrap.min.css';
import { Container, Button } from 'react-bootstrap';

function App() {
  const [greetMsg, setGreetMsg] = useState("");
  const [hoge, setHoge] = useState("");

  async function getHoge() {
    // Learn more about Tauri commands at <https://tauri.app/v1/guides/features/command>
    const hoge_hoge: String = hoge;
    setGreetMsg(await invoke("greet", { hoge_hoge }));
  }

  return (
    <Container>
        <form
            className="form-inline"
            onSubmit={(e) => {
                e.preventDefault();
                getHoge();
            }}
        >
        </form>
      <p>{greetMsg}</p>
    </Container>
  );
}

export default App;

不要な部分を省略したり簡素化したりしていますが、サンプルを少し弄った程度です。ボタン押下時にその値を state に hoge という名前で代入し、それを非同期関数内で取り出して(実際は加工をしています)別の変数 hoge_hoge に代入、 hoge_hoge を Rust 側へ引数として渡す、というイメージです。

Rust (main.rs)

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use serde_json;
//use std::io::Write;

// Learn more about Tauri commands at <https://tauri.app/v1/guides/features/command>
#[tauri::command]
fn greet(hoge_hoge: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", hoge_hoge)
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Rust 側は先の処理のところで躓いてしまったので、サンプルから変更していない状態です。

最初にここを弄り始めた際に tsx と Rust 側で変数名は同じにしないとエラーになると気付いたこと、その上で Rust 側は変数名をスネークケースで記述しないと忠告されるのでスネークケースで記述し、 tsx 側も意図的に同じ名前にしました。

すると、先のエラーが yarn tauri dev で起動した開発中のブラウザのコンソールログで出力される、という状態です。

原因

妙なのは、エラーで出力されている変数名 hogeHoge は tsx 側には存在していないということです。先述の通り、意図的に変数名は hoge_hoge としているので……。

そこで軽く詰まってしまったのですが、むしろ「同じ名前にする」というところに固執し過ぎていたことが原因でした。正しくは以下のようなコードになります。

import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
import 'bootstrap/dist/css/bootstrap.min.css';
import { Container, Button } from 'react-bootstrap';

function App() {
  const [greetMsg, setGreetMsg] = useState("");
  const [hoge, setHoge] = useState("");

  async function getHoge() {
    // Learn more about Tauri commands at <https://tauri.app/v1/guides/features/command>
    const hogeHoge: String = hoge;
    setGreetMsg(await invoke("greet", { hogeHoge }));
  }

  return (
    <Container>
        <form
            className="form-inline"
            onSubmit={(e) => {
                e.preventDefault();
                getHoge();
            }}
        >
        </form>
      <p>{greetMsg}</p>
    </Container>
  );
}

export default App;

そう、 tsx 側はスネークケースではなくキャメルケースで記述 (hoge_hoge ではなく hogeHoge) するのが正解。これで Rust 側の hoge_hoge と対応が取れます。

そういえば css のプロパティ名を JavaScript で記述する際もキャメルケースで普通に解釈されていましたし……ということに気付けば何と言うことはないのですが、久々にコードを書いたので気付くまでに時間がかかってしまいました (そしてエラー文で検索しても情報が得られなかったので)。

参考?

エラー文で検索して近い文章がヒットしたケース。実際はここから直接答えには到達しなかったのですが……。

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。