guan404ming commented on code in PR #399:
URL: https://github.com/apache/tvm-ffi/pull/399#discussion_r2723622389
##########
include/tvm/ffi/function.h:
##########
@@ -643,6 +643,51 @@ 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) {
+ // Success - cast result to T and return Ok
+ return Expected<T>::Ok(std::move(result).cast<T>());
Review Comment:
Nice catch. The implementation looks good. I think there is a potential edge
case that we probably don't want ot try casting if `T = Any`. Here is updated
implementation
```c
if (ret_code == 0) {
if constexpr (std::is_same_v<T, Any>) {
return Expected<T>::Ok(std::move(result));
} else {
if (auto val = std::move(result).template as<T>()) {
return Expected<T>::Ok(std::move(*val));
} else {
return Expected<T>::Err(Error(
"TypeError",
"CallExpected: result type mismatch, expected " +
TypeTraits<T>::TypeStr(), ""));
}
}
}
```
--
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]