diff --git a/Cargo.toml b/Cargo.toml index a9bf91c1..2776468d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "./examples/tauri/src-tauri", "./examples/legacy", "./examples/binario", + "./examples/anyhow", ] [workspace.dependencies] diff --git a/examples/anyhow/Cargo.toml b/examples/anyhow/Cargo.toml new file mode 100644 index 00000000..aff7d6ff --- /dev/null +++ b/examples/anyhow/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "example-anyhow" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +rspc = { path = "../../rspc", features = ["typescript"] } +specta.workspace = true +anyhow = "1.0.95" +thiserror = "2.0.11" + +[lints] +workspace = true diff --git a/examples/anyhow/bindings.ts b/examples/anyhow/bindings.ts new file mode 100644 index 00000000..e4d63e90 --- /dev/null +++ b/examples/anyhow/bindings.ts @@ -0,0 +1,5 @@ +// This file was generated by [rspc](https://github.com/specta-rs/rspc). Do not edit this file manually. + +export type Procedures = { + anyhow: { kind: "query", input: any, output: any, error: any }, +} \ No newline at end of file diff --git a/examples/anyhow/src/main.rs b/examples/anyhow/src/main.rs new file mode 100644 index 00000000..e1f6d2ad --- /dev/null +++ b/examples/anyhow/src/main.rs @@ -0,0 +1,45 @@ +use rspc::{Procedure, Router}; +use specta::Type; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +fn main() { + let (_procedures, _types) = Router::new() + .procedure( + // + "anyhow", + Procedure::builder().query(anyhow_procedure), + ) + .build() + .expect("router should be built"); +} + +// Some procedure that needs `anyhow::Error` to be compatible with `rspc`. +async fn anyhow_procedure(_ctx: (), _input: ()) -> Result { + let response = fallible()?; // `?` converts `anyhow::Error` into `AnyhowError`. + Ok(response) +} + +fn fallible() -> Result { + anyhow::bail!("oh no!") +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Make `anyhow::Error` work where `std::error::Error + Send + 'static` is expected. +// NB: Define this only once; afterwards, you can import and use it anywhere. +// See: https://github.com/dtolnay/anyhow/issues/153#issuecomment-833718851 +#[derive(Debug, thiserror::Error, Type)] +#[error(transparent)] +struct AnyhowError( + #[from] + #[serde(skip)] + anyhow::Error, +); + +impl rspc::Error for AnyhowError { + fn into_procedure_error(self) -> rspc::ProcedureError { + let message = format!("something bad happened: {}", self); + rspc::ResolverError::new(message, Some(self)).into() + } +}