From 4b9a7ef93365b8792d96f245453dafffc8eb97bf Mon Sep 17 00:00:00 2001 From: Mashed Potato <38517644+potatomashed@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:37:56 -0700 Subject: [PATCH] fix(core): Properly Handle No Error Message --- cpp/c_api.cc | 5 +++++ python/mlc/_cython/base.py | 5 ++++- tests/python/test_cython_traceback.py | 22 ++++++++++++++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/cpp/c_api.cc b/cpp/c_api.cc index a9d138bf..aab2aa40 100644 --- a/cpp/c_api.cc +++ b/cpp/c_api.cc @@ -389,6 +389,11 @@ MLC_REGISTER_FUNC("mlc.testing.throw_exception_from_c").set_body([]() { MLC_THROW(ValueError) << "This is an error message"; }); +MLC_REGISTER_FUNC("mlc.testing.throw_exception_from_c_empty").set_body([]() { + // Throw an exception in C++ with no message + MLC_THROW(ValueError); +}); + MLC_REGISTER_FUNC("mlc.testing.throw_exception_from_ffi_in_c").set_body([](FuncObj *func) { // call a Python function which throws an exception (*func)(); diff --git a/python/mlc/_cython/base.py b/python/mlc/_cython/base.py index bb9396ee..dee51191 100644 --- a/python/mlc/_cython/base.py +++ b/python/mlc/_cython/base.py @@ -259,7 +259,10 @@ def translate_exception_from_c(err: Error) -> Exception: from .core import error_pycode_fake # type: ignore[import-not-found] kind, info = err.kind, err._info - msg, info = info[0], info[1:] + if info: + msg, info = info[0], info[1:] + else: + msg = "" if kind in ERR_KIND2CLS: exception = ERR_KIND2CLS[kind](msg) else: diff --git a/tests/python/test_cython_traceback.py b/tests/python/test_cython_traceback.py index 0d27025a..0fd5ac24 100644 --- a/tests/python/test_cython_traceback.py +++ b/tests/python/test_cython_traceback.py @@ -15,8 +15,19 @@ def test_throw_exception_from_c() -> None: assert "Traceback (most recent call last)" in msg[0] assert "in test_throw_exception_from_c" in msg[1] assert "ValueError: This is an error message" in msg[-1] - if mlc._cython.SYSTEM != "Darwin": - assert "c_api.cc" in msg[-3] + assert "c_api.cc" in msg[-3] + + +def test_throw_exception_from_c_empty() -> None: + func = mlc.Func.get("mlc.testing.throw_exception_from_c_empty") + with pytest.raises(ValueError) as exc_info: + func() + + msg = traceback.format_exception(exc_info.type, exc_info.value, exc_info.tb) + msg = "".join(msg).strip().splitlines() + assert "Traceback (most recent call last)" in msg[0] + assert "in test_throw_exception_from_c_empty" in msg[1] + assert "ValueError" == msg[-1].strip() def test_throw_exception_from_ffi() -> None: @@ -49,10 +60,9 @@ def _inner() -> None: assert "Traceback (most recent call last)" in msg[0] assert "in test_throw_exception_from_ffi_in_c" in msg[1] assert "ValueError: This is a ValueError" in msg[-1] - if mlc._cython.SYSTEM != "Darwin": - idx_c_api_tests = next(i for i, line in enumerate(msg) if "c_api.cc" in line) - idx_handle_error = next(i for i, line in enumerate(msg) if "_func_safe_call_impl" in line) - assert idx_c_api_tests < idx_handle_error + idx_c_api_tests = next(i for i, line in enumerate(msg) if "c_api.cc" in line) + idx_handle_error = next(i for i, line in enumerate(msg) if "_func_safe_call_impl" in line) + assert idx_c_api_tests < idx_handle_error def test_throw_NotImplementedError_from_ffi_in_c() -> None: