From 333c558d78bd1c67f1a1b00a8706536e9a15cd81 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 21 Jun 2025 15:20:25 -0700 Subject: [PATCH] [capi] expose error strings --- temporal_capi/bindings/c/TemporalError.d.h | 1 + .../cpp/temporal_rs/TemporalError.d.hpp | 2 ++ .../bindings/cpp/temporal_rs/TemporalError.hpp | 2 ++ temporal_capi/src/error.rs | 17 ++++++++++++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/temporal_capi/bindings/c/TemporalError.d.h b/temporal_capi/bindings/c/TemporalError.d.h index 9b2953996..3c37cf5f3 100644 --- a/temporal_capi/bindings/c/TemporalError.d.h +++ b/temporal_capi/bindings/c/TemporalError.d.h @@ -14,6 +14,7 @@ typedef struct TemporalError { ErrorKind kind; + OptionStringView msg; } TemporalError; typedef struct TemporalError_option {union { TemporalError ok; }; bool is_ok; } TemporalError_option; diff --git a/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp index 2d59a55fd..05d57287e 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/TemporalError.d.hpp @@ -21,6 +21,7 @@ namespace temporal_rs { namespace capi { struct TemporalError { temporal_rs::capi::ErrorKind kind; + diplomat::capi::OptionStringView msg; }; typedef struct TemporalError_option {union { TemporalError ok; }; bool is_ok; } TemporalError_option; @@ -31,6 +32,7 @@ namespace capi { namespace temporal_rs { struct TemporalError { temporal_rs::ErrorKind kind; + std::optional msg; inline temporal_rs::capi::TemporalError AsFFI() const; inline static temporal_rs::TemporalError FromFFI(temporal_rs::capi::TemporalError c_struct); diff --git a/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp b/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp index 207949ac2..eb8dc32f7 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/TemporalError.hpp @@ -27,12 +27,14 @@ namespace capi { inline temporal_rs::capi::TemporalError temporal_rs::TemporalError::AsFFI() const { return temporal_rs::capi::TemporalError { /* .kind = */ kind.AsFFI(), + /* .msg = */ msg.has_value() ? (diplomat::capi::OptionStringView{ { {msg.value().data(), msg.value().size()} }, true }) : (diplomat::capi::OptionStringView{ {}, false }), }; } inline temporal_rs::TemporalError temporal_rs::TemporalError::FromFFI(temporal_rs::capi::TemporalError c_struct) { return temporal_rs::TemporalError { /* .kind = */ temporal_rs::ErrorKind::FromFFI(c_struct.kind), + /* .msg = */ c_struct.msg.is_ok ? std::optional(std::string_view(c_struct.msg.ok.data, c_struct.msg.ok.len)) : std::nullopt, }; } diff --git a/temporal_capi/src/error.rs b/temporal_capi/src/error.rs index f385d459b..8e58bfbe3 100644 --- a/temporal_capi/src/error.rs +++ b/temporal_capi/src/error.rs @@ -1,7 +1,11 @@ +use alloc::borrow::Cow; + #[diplomat::bridge] #[diplomat::abi_rename = "temporal_rs_{0}"] #[diplomat::attr(auto, namespace = "temporal_rs")] pub mod ffi { + use diplomat_runtime::{DiplomatOption, DiplomatUtf8StrSlice}; + #[diplomat::enum_convert(temporal_rs::error::ErrorKind)] pub enum ErrorKind { Generic, @@ -14,6 +18,7 @@ pub mod ffi { // In the future we might turn this into an opaque type with a msg() field pub struct TemporalError { pub kind: ErrorKind, + pub msg: DiplomatOption>, } impl TemporalError { @@ -21,12 +26,14 @@ pub mod ffi { pub(crate) fn syntax() -> Self { TemporalError { kind: ErrorKind::Syntax, + msg: None.into(), } } pub(crate) fn range() -> Self { TemporalError { kind: ErrorKind::Range, + msg: None.into(), } } } @@ -34,8 +41,16 @@ pub mod ffi { impl From for ffi::TemporalError { fn from(other: temporal_rs::TemporalError) -> Self { + let kind = other.kind().into(); + let msg = other.into_message(); + let msg = if let Cow::Borrowed(s) = msg { + Some(s) + } else { + None + }; Self { - kind: other.kind().into(), + kind, + msg: msg.map(Into::into).into(), } } }