最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rust - async tauri command returning dynamic error, does not implement necessary traits - Stack Overflow

programmeradmin1浏览0评论

im trying to give a client application email functionality using lettre and tokio.

The code itself should work, though declaring the function a tauri::command gives problems, i don't know how to solve.

#[tauri::command]
async fn send_email(
    from: &str,    
    to: &str,    
    subject: &str,   
    body: String,) 
->Result<(), Box<dyn std::error::Error>> {
    let smtp_credentials: Credentials =
        Credentials::new("smtp_username".to_string(), "smtp_password".to_string());

    let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.email")?
        .credentials(smtp_credentials)
        .build();

    let email = Message::builder()
        .from(from.parse()?)
        .to(to.parse()?)
        .subject(subject)
        .body(body.to_string())?;

    mailer.send(email).await?;

    Ok(())
}

throwing me the error:

the method `async_kind` exists for reference `&impl Future<Output = Result<(), Box<dyn Error>>>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: IpcResponse`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResponseKind`
`<&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>> as Future>::Output = Result<_, _>`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResultFutureKind`
`&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: Future`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResultFutureKind`


i have tried impl the Future trait for the return type of my function like:

send_mail (...) ->impl Future <Output = Result<(), Box<dyn std::error::Error>>> {

to no success

the problems seems to be the return value of a dynamic error because the standard library error does not impl Future but trying to implement the trait for the dyn Error or Box of typ dyn Error is not possible.

I know i could refactor my code so the tauri command invokes my async function,letting it handle the dyn Error by propegation so eliminating to use both in one but i would at least like to know why this error is caused/how to fix it properly.

Im fairly new to rust/tauri, and while i like to think to understand the concepts and restriction but im still fighting with the expected syntax.

thanks in advance for the help

im trying to give a client application email functionality using lettre and tokio.

The code itself should work, though declaring the function a tauri::command gives problems, i don't know how to solve.

#[tauri::command]
async fn send_email(
    from: &str,    
    to: &str,    
    subject: &str,   
    body: String,) 
->Result<(), Box<dyn std::error::Error>> {
    let smtp_credentials: Credentials =
        Credentials::new("smtp_username".to_string(), "smtp_password".to_string());

    let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.email")?
        .credentials(smtp_credentials)
        .build();

    let email = Message::builder()
        .from(from.parse()?)
        .to(to.parse()?)
        .subject(subject)
        .body(body.to_string())?;

    mailer.send(email).await?;

    Ok(())
}

throwing me the error:

the method `async_kind` exists for reference `&impl Future<Output = Result<(), Box<dyn Error>>>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: IpcResponse`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResponseKind`
`<&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>> as Future>::Output = Result<_, _>`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResultFutureKind`
`&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: Future`
which is required by `&impl Future<Output = Result<(), Box<(dyn std::error::Error + 'static)>>>: tauri::ipc::private::ResultFutureKind`


i have tried impl the Future trait for the return type of my function like:

send_mail (...) ->impl Future <Output = Result<(), Box<dyn std::error::Error>>> {

to no success

the problems seems to be the return value of a dynamic error because the standard library error does not impl Future but trying to implement the trait for the dyn Error or Box of typ dyn Error is not possible.

I know i could refactor my code so the tauri command invokes my async function,letting it handle the dyn Error by propegation so eliminating to use both in one but i would at least like to know why this error is caused/how to fix it properly.

Im fairly new to rust/tauri, and while i like to think to understand the concepts and restriction but im still fighting with the expected syntax.

thanks in advance for the help

Share Improve this question asked Mar 19 at 15:26 Yawgmoth-PhysicianYawgmoth-Physician 31 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

In short, the error type needs to implement Serialize which Box<dyn Error> does not.

The Tauri docs have a section on error-handling. From there:

  • If you want a quick-and-dirty solution, use String as the error type and stringify the errors yourself. The docs show this as an example:

    #[tauri::command]
    fn my_custom_command() -> Result<(), String> {
      std::fs::File::open("path/to/file").map_err(|err| err.to_string())?;
      // Return `null` on success
      Ok(())
    }
    
  • Or the better solution is to create your own error enum type (maybe with the help of thiserror) that encapsulates all the possible errors. The docs show this as an example:

    // create the error type that represents all errors possible in our program
    #[derive(Debug, thiserror::Error)]
    enum Error {
      #[error(transparent)]
      Io(#[from] std::io::Error)
    }
    
    // we must manually implement serde::Serialize
    impl serde::Serialize for Error {
      fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
      where
        S: serde::ser::Serializer,
      {
        serializer.serialize_str(self.to_string().as_ref())
      }
    }
    
    #[tauri::command]
    fn my_custom_command() -> Result<(), Error> {
      // This will return an error
      std::fs::File::open("path/that/does/not/exist")?;
      // Return `null` on success
      Ok(())
    }
    

There is more there than just these examples; I encourage you to read through it.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论