From a3619e3c5d9a0299f1284c8e29ec94ba6213fc48 Mon Sep 17 00:00:00 2001 From: Lev Khoroshansky Date: Mon, 3 Feb 2025 18:18:45 +0100 Subject: [PATCH 1/2] feat: Add `anyhow::Error` example --- Cargo.toml | 1 + examples/anyhow-error/Cargo.toml | 13 ++++++++++ examples/anyhow-error/bindings.ts | 5 ++++ examples/anyhow-error/src/main.rs | 40 +++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 examples/anyhow-error/Cargo.toml create mode 100644 examples/anyhow-error/bindings.ts create mode 100644 examples/anyhow-error/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index a9bf91c1..faabc62d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "./examples/tauri/src-tauri", "./examples/legacy", "./examples/binario", + "./examples/anyhow-error", ] [workspace.dependencies] diff --git a/examples/anyhow-error/Cargo.toml b/examples/anyhow-error/Cargo.toml new file mode 100644 index 00000000..9bccbd18 --- /dev/null +++ b/examples/anyhow-error/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "anyhow-error" +version = "0.1.0" +edition = "2021" + +[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-error/bindings.ts b/examples/anyhow-error/bindings.ts new file mode 100644 index 00000000..e4d63e90 --- /dev/null +++ b/examples/anyhow-error/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-error/src/main.rs b/examples/anyhow-error/src/main.rs new file mode 100644 index 00000000..1caf6a32 --- /dev/null +++ b/examples/anyhow-error/src/main.rs @@ -0,0 +1,40 @@ +use rspc::{Procedure, Router}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +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)] +#[error(transparent)] +struct AnyhowError(#[from] 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() + } +} From c5b37e699d1753a81457cf7f55d2b29d63fa70f6 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Fri, 7 Feb 2025 15:38:24 +1100 Subject: [PATCH 2/2] nit --- Cargo.toml | 2 +- examples/{anyhow-error => anyhow}/Cargo.toml | 5 +++-- examples/{anyhow-error => anyhow}/bindings.ts | 0 examples/{anyhow-error => anyhow}/src/main.rs | 9 +++++++-- 4 files changed, 11 insertions(+), 5 deletions(-) rename examples/{anyhow-error => anyhow}/Cargo.toml (76%) rename examples/{anyhow-error => anyhow}/bindings.ts (100%) rename examples/{anyhow-error => anyhow}/src/main.rs (90%) diff --git a/Cargo.toml b/Cargo.toml index faabc62d..2776468d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ "./examples/tauri/src-tauri", "./examples/legacy", "./examples/binario", - "./examples/anyhow-error", + "./examples/anyhow", ] [workspace.dependencies] diff --git a/examples/anyhow-error/Cargo.toml b/examples/anyhow/Cargo.toml similarity index 76% rename from examples/anyhow-error/Cargo.toml rename to examples/anyhow/Cargo.toml index 9bccbd18..aff7d6ff 100644 --- a/examples/anyhow-error/Cargo.toml +++ b/examples/anyhow/Cargo.toml @@ -1,7 +1,8 @@ [package] -name = "anyhow-error" -version = "0.1.0" +name = "example-anyhow" +version = "0.0.0" edition = "2021" +publish = false [dependencies] rspc = { path = "../../rspc", features = ["typescript"] } diff --git a/examples/anyhow-error/bindings.ts b/examples/anyhow/bindings.ts similarity index 100% rename from examples/anyhow-error/bindings.ts rename to examples/anyhow/bindings.ts diff --git a/examples/anyhow-error/src/main.rs b/examples/anyhow/src/main.rs similarity index 90% rename from examples/anyhow-error/src/main.rs rename to examples/anyhow/src/main.rs index 1caf6a32..e1f6d2ad 100644 --- a/examples/anyhow-error/src/main.rs +++ b/examples/anyhow/src/main.rs @@ -1,4 +1,5 @@ use rspc::{Procedure, Router}; +use specta::Type; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,9 +29,13 @@ fn fallible() -> Result { // 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)] +#[derive(Debug, thiserror::Error, Type)] #[error(transparent)] -struct AnyhowError(#[from] anyhow::Error); +struct AnyhowError( + #[from] + #[serde(skip)] + anyhow::Error, +); impl rspc::Error for AnyhowError { fn into_procedure_error(self) -> rspc::ProcedureError {