guan404ming commented on code in PR #399:
URL: https://github.com/apache/tvm-ffi/pull/399#discussion_r2760043569
##########
include/tvm/ffi/function.h:
##########
@@ -643,6 +643,65 @@ class Function : public ObjectRef {
static_cast<FunctionObj*>(data_.get())->CallPacked(args.data(),
args.size(), result);
}
+ /*!
+ * \brief Call the function and return Expected<T> for exception-free error
handling.
+ * \tparam T The expected return type (default: Any).
+ * \param args The arguments to pass to the function.
+ * \return Expected<T> containing either the result or an error.
+ *
+ * This method provides exception-free calling by catching all exceptions
+ * and returning them as Error values in the Expected type.
+ *
+ * \code
+ * Function func = Function::GetGlobal("risky_function");
+ * Expected<int> result = func.CallExpected<int>(arg1, arg2);
+ * if (result.is_ok()) {
+ * int value = result.value();
+ * } else {
+ * Error err = result.error();
+ * }
+ * \endcode
+ */
+ template <typename T = Any, typename... Args>
+ TVM_FFI_INLINE Expected<T> CallExpected(Args&&... args) const {
+ constexpr size_t kNumArgs = sizeof...(Args);
+ AnyView args_pack[kNumArgs > 0 ? kNumArgs : 1];
+ PackedArgs::Fill(args_pack, std::forward<Args>(args)...);
+
+ Any result;
+ FunctionObj* func_obj = static_cast<FunctionObj*>(data_.get());
+
+ // Use safe_call path to catch exceptions
+ int ret_code = func_obj->safe_call(func_obj, reinterpret_cast<const
TVMFFIAny*>(args_pack),
+ kNumArgs,
reinterpret_cast<TVMFFIAny*>(&result));
+
+ if (ret_code == 0) {
+ if constexpr (std::is_same_v<T, Any>) {
+ return std::move(result);
+ } else {
+ // Check if result is Error (from Expected-returning function that
returned Err)
+ if (result.template as<Error>().has_value()) {
+ return std::move(result).template cast<Error>();
+ }
+ // Try to extract as T
+ if (auto val = result.template try_cast<T>()) {
+ return std::move(*val);
+ }
+ return Error("TypeError",
+ "CallExpected: result type mismatch, expected " +
TypeTraits<T>::TypeStr() +
+ ", but got " + result.GetTypeKey(),
+ "");
+ }
+ } else if (ret_code == -2) {
+ // Environment error already set (e.g., Python KeyboardInterrupt)
+ // We still throw this since it's a signal, not a normal error
Review Comment:
Just removed, thanks for the pr!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]