tenho seguinte código tauri rust v2

use serde::{Deserialize, Serialize};
use std::{
    fs::{self, File},
    io::{self, Write},
    path::{Path, PathBuf},
};

use tauri::{AppHandle, Emitter}; // Importando a trait Emitter
use reqwest::Client;

#[derive(Debug, Deserialize)]
struct PatchEntry {
    //version: u32,
    file_name: String,
    //target: String,
    //integrity: String,
}

#[derive(Debug, Serialize, Clone)]
struct DownloadMessage {
    message: String,
}

#[derive(Debug, Serialize, Clone)]
struct DownloadInfo {
    current_file: usize,
    total_files: usize,
    file_name: String,
    downloaded_bytes: u64,
    total_bytes: u64,
}

fn get_exe_dir() -> PathBuf {
    std::env::current_exe()
        .unwrap()
        .parent()
        .unwrap()
        .to_path_buf()
}

fn read_patch_file(path: &Path) -> io::Result<Vec<PatchEntry>> {
    let file = File::open(path)?;
    let patches: Vec<PatchEntry> = serde_json::from_reader(file)?;
    Ok(patches)
}

async fn download_file(
  app_handle: &AppHandle,
  client: &Client,
  entry: PatchEntry,
  download_dir: &Path,
  current_file: usize,
  total_files: usize,
) -> Result<(), Box<dyn std::error::Error>> {
  let url = format!("https://hil-speed.hetzner.com/{}", entry.file_name);
  let file_path = download_dir.join(&entry.file_name);

  // Emitindo um evento de início do download
  /*app_handle.emit(
      "download_update",
      DownloadMessage {
          message: "Iniciando download".to_string(),
      },
  )?;*/

  let mut response = client.get(&url).send().await?;
  let total_bytes = response.content_length().unwrap_or(0);
  let mut file = File::create(&file_path)?;

  let mut downloaded_bytes = 0;

  // Lendo o corpo da resposta
  while let Some(chunk) = response.chunk().await? {
      file.write_all(&chunk)?;
      downloaded_bytes += chunk.len() as u64;

      app_handle.emit(
        "download_update",
        DownloadMessage {
            message: "Baixando".to_string(),
        },
      )?;

      app_handle.emit(
          "download_info",
          DownloadInfo {
              current_file,
              total_files,
              file_name: entry.file_name.clone(),
              downloaded_bytes,
              total_bytes,
          },
      )?;
  }

  // Download concluído
  app_handle.emit(
      "download_update",
      DownloadMessage {
          message: "Download concluído".to_string(),
      },
  )?;

  Ok(())
}

async fn check_server_connection(client: &Client, url: &str) -> Result<(), Box<dyn std::error::Error>> {
  let response = client.get(url).send().await?;
  if response.status().is_success() {
      Ok(())
  } else {
      Err("Failed to connect to the server".into())
  }
}

#[tauri::command]
pub async fn start_downloads(app_handle: AppHandle) -> Result<(), String> {
  let exe_dir = get_exe_dir();
  let patch_file_path = exe_dir.join("patch.json");
  let download_dir = exe_dir.join("patchs");

  if !download_dir.exists() {
      fs::create_dir_all(&download_dir).map_err(|e| e.to_string())?;
  }

  let patches = read_patch_file(&patch_file_path).map_err(|e| e.to_string())?;
  let client = Client::new();
  let total_files = patches.len();

  app_handle.emit(
    "download_update",
    DownloadMessage {
        message: "Conectando ao servidor...".to_string(),
    },
  )?;

  // Verifique a conexão com o servidor
  let server_url = "https://hil-speed.hetzner.com/";
  if let Err(err) = check_server_connection(&client, server_url).await {
      app_handle.emit(
          "download_update",
          DownloadMessage {
              message: format!("Erro ao conectar ao servidor: {}", err),
          },
      )?;
      return Err(format!("Erro ao conectar ao servidor: {}", err));
  }

  // Se a conexão for bem-sucedida
  app_handle.emit(
      "download_update",
      DownloadMessage {
          message: "Conexão estabelecida com sucesso. Iniciando download...".to_string(),
      },
  )?;

  for (current_file, entry) in patches.into_iter().enumerate() {
      let current_file = current_file + 1; // Índice baseado em 1
      if let Err(err) = download_file(&app_handle, &client, entry, &download_dir, current_file, total_files).await {
          eprintln!("Erro ao baixar arquivo: {}", err);
      }
  }

  Ok(())
}

recebo erro

error: could not compile `RagnaTales` (lib) due to 3 previous errors; 1 warning emitted
    Info File src-tauri\src\download.rs changed. Rebuilding application...
   Compiling RagnaTales v0.1.0 (C:\Users\jonatas\Desktop\Megasantos\_RagnaTalesReact\src-tauri)
error[E0277]: `?` couldn't convert the error to `std::string::String`
   --> src\download.rs:135:4
    |
135 |   )?;
    |    ^ the trait `From<tauri::Error>` is not implemented for `std::string::String`, which is required by `Result<(), std::string::String>: FromResidual<Result<Infallible, tauri::Error>>`  
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              <std::string::String as From<&'a tendril::tendril::Tendril<tendril::fmt::UTF8, A>>>
              <std::string::String as From<&mut str>>
              <std::string::String as From<&std::string::String>>
              <std::string::String as From<&str>>
              <std::string::String as From<AssetKey>>
              <std::string::String as From<Box<str>>>
              <std::string::String as From<Cow<'a, str>>>
              <std::string::String as From<char>>
            and 3 others
    = note: required for `Result<(), std::string::String>` to implement `FromResidual<Result<Infallible, tauri::Error>>`

error[E0277]: `?` couldn't convert the error to `std::string::String`
   --> src\download.rs:145:8
    |
145 |       )?;
    |        ^ the trait `From<tauri::Error>` is not implemented for `std::string::String`, which is required by `Result<(), std::string::String>: FromResidual<Result<Infallible, tauri::Error>>`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              <std::string::String as From<&'a tendril::tendril::Tendril<tendril::fmt::UTF8, A>>>
              <std::string::String as From<&mut str>>
              <std::string::String as From<&std::string::String>>
              <std::string::String as From<&str>>
              <std::string::String as From<AssetKey>>
              <std::string::String as From<Box<str>>>
              <std::string::String as From<Cow<'a, str>>>
              <std::string::String as From<char>>
            and 3 others
    = note: required for `Result<(), std::string::String>` to implement `FromResidual<Result<Infallible, tauri::Error>>`

error[E0277]: `?` couldn't convert the error to `std::string::String`
   --> src\download.rs:155:4
    |
155 |   )?;
    |    ^ the trait `From<tauri::Error>` is not implemented for `std::string::String`, which is required by `Result<(), std::string::String>: FromResidual<Result<Infallible, tauri::Error>>`  
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              <std::string::String as From<&'a tendril::tendril::Tendril<tendril::fmt::UTF8, A>>>
              <std::string::String as From<&mut str>>
              <std::string::String as From<&std::string::String>>
              <std::string::String as From<&str>>
              <std::string::String as From<AssetKey>>
              <std::string::String as From<Box<str>>>
              <std::string::String as From<Cow<'a, str>>>
              <std::string::String as From<char>>
            and 3 others
    = note: required for `Result<(), std::string::String>` to implement `FromResidual<Result<Infallible, tauri::Error>>`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `RagnaTales` (lib) due to 3 previous errors