This is an automated email from the ASF dual-hosted git repository.

junrushao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git


The following commit(s) were added to refs/heads/main by this push:
     new 4bccb3e  [ERROR] Make Error conform more to std (#240)
4bccb3e is described below

commit 4bccb3eda0d543be67ec56204e045ca3e3b88641
Author: Tianqi Chen <[email protected]>
AuthorDate: Fri Nov 7 20:05:20 2025 -0500

    [ERROR] Make Error conform more to std (#240)
    
    This PR changes Error.what() to only return message. This helps to
    conform to the standard that what should not throw. Added a
    error.FullMessage() function to get the fullmessage with trace and kind.
    
    This also helps us to remove TLS in the header side which can makes the
    compiled c++ object more friendly wrt to LLVM JIT.
---
 include/tvm/ffi/error.h | 20 ++++++++++++++------
 tests/cpp/test_error.cc | 32 +++++++++++++++++---------------
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/include/tvm/ffi/error.h b/include/tvm/ffi/error.h
index dd7b923..9560237 100644
--- a/include/tvm/ffi/error.h
+++ b/include/tvm/ffi/error.h
@@ -225,17 +225,25 @@ class Error : public ObjectRef, public std::exception {
     obj->update_backtrace(obj, backtrace_str, update_mode);
   }
 
+  /*!
+   * \brief Get the full message of the error, including kind, message and 
traceback.
+   * \return The full message of the error object.
+   */
+  std::string FullMessage() const {
+    ErrorObj* obj = static_cast<ErrorObj*>(data_.get());
+    return (std::string("Traceback (most recent call last):\n") + 
TracebackMostRecentCallLast() +
+            std::string(obj->kind.data, obj->kind.size) + std::string(": ") +
+            std::string(obj->message.data, obj->message.size) + '\n');
+  }
+
   /*!
    * \brief Get the error message
    * \return The error message
+   * \note To get the full message including kind and traceback, use 
FullMessage() instead.
    */
   const char* what() const noexcept(true) override {
-    thread_local std::string what_data;
     ErrorObj* obj = static_cast<ErrorObj*>(data_.get());
-    what_data = (std::string("Traceback (most recent call last):\n") +
-                 TracebackMostRecentCallLast() + std::string(obj->kind.data, 
obj->kind.size) +
-                 std::string(": ") + std::string(obj->message.data, 
obj->message.size) + '\n');
-    return what_data.c_str();
+    return obj->message.data;
   }
 
   /// \cond Doxygen_Suppress
@@ -265,7 +273,7 @@ class ErrorBuilder {
   [[noreturn]] ~ErrorBuilder() noexcept(false) {
     ::tvm::ffi::Error error(std::move(kind_), stream_.str(), 
std::move(backtrace_));
     if (log_before_throw_) {
-      std::cerr << error.what();
+      std::cerr << error.FullMessage();
     }
     throw error;
   }
diff --git a/tests/cpp/test_error.cc b/tests/cpp/test_error.cc
index 46ffe7c..283e4b9 100644
--- a/tests/cpp/test_error.cc
+++ b/tests/cpp/test_error.cc
@@ -35,10 +35,10 @@ TEST(Error, Backtrace) {
         } catch (const Error& error) {
           EXPECT_EQ(error.message(), "test0");
           EXPECT_EQ(error.kind(), "RuntimeError");
-          std::string what = error.what();
-          EXPECT_NE(what.find("line"), std::string::npos);
-          EXPECT_NE(what.find("ThrowRuntimeError"), std::string::npos);
-          EXPECT_NE(what.find("RuntimeError: test0"), std::string::npos);
+          std::string full_message = error.FullMessage();
+          EXPECT_NE(full_message.find("line"), std::string::npos);
+          EXPECT_NE(full_message.find("ThrowRuntimeError"), std::string::npos);
+          EXPECT_NE(full_message.find("RuntimeError: test0"), 
std::string::npos);
           throw;
         }
       },
@@ -52,9 +52,9 @@ TEST(CheckError, Backtrace) {
           TVM_FFI_ICHECK_GT(2, 3);
         } catch (const Error& error) {
           EXPECT_EQ(error.kind(), "InternalError");
-          std::string what = error.what();
-          EXPECT_NE(what.find("line"), std::string::npos);
-          EXPECT_NE(what.find("2 > 3"), std::string::npos);
+          std::string full_message = error.FullMessage();
+          EXPECT_NE(full_message.find("line"), std::string::npos);
+          EXPECT_NE(full_message.find("2 > 3"), std::string::npos);
           throw;
         }
       },
@@ -69,10 +69,10 @@ TEST(CheckError, ValueError) {
           TVM_FFI_CHECK(value >= 0, ValueError) << "Value must be 
non-negative, got " << value;
         } catch (const Error& error) {
           EXPECT_EQ(error.kind(), "ValueError");
-          std::string what = error.what();
-          EXPECT_NE(what.find("line"), std::string::npos);
-          EXPECT_NE(what.find("Check failed: (value >= 0) is false"), 
std::string::npos);
-          EXPECT_NE(what.find("Value must be non-negative, got -5"), 
std::string::npos);
+          std::string full_message = error.FullMessage();
+          EXPECT_NE(full_message.find("line"), std::string::npos);
+          EXPECT_NE(full_message.find("Check failed: (value >= 0) is false"), 
std::string::npos);
+          EXPECT_NE(full_message.find("Value must be non-negative, got -5"), 
std::string::npos);
           throw;
         }
       },
@@ -89,10 +89,12 @@ TEST(CheckError, IndexError) {
               << "Index " << index << " out of bounds for array of size " << 
array_size;
         } catch (const Error& error) {
           EXPECT_EQ(error.kind(), "IndexError");
-          std::string what = error.what();
-          EXPECT_NE(what.find("line"), std::string::npos);
-          EXPECT_NE(what.find("Check failed: (index < array_size) is false"), 
std::string::npos);
-          EXPECT_NE(what.find("Index 10 out of bounds for array of size 5"), 
std::string::npos);
+          std::string full_message = error.FullMessage();
+          EXPECT_NE(full_message.find("line"), std::string::npos);
+          EXPECT_NE(full_message.find("Check failed: (index < array_size) is 
false"),
+                    std::string::npos);
+          EXPECT_NE(full_message.find("Index 10 out of bounds for array of 
size 5"),
+                    std::string::npos);
           throw;
         }
       },

Reply via email to