Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CAPI] add ov_get_last_error_msg() API #20643

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/bindings/c/include/openvino/c/ov_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,10 @@ ov_get_error_info(ov_status_e status);
*/
OPENVINO_C_API(void)
ov_free(const char* content);

/**
* @brief Get the last error msg.
* @ingroup ov_base_c_api
*/
OPENVINO_C_API(const char*)
ov_get_last_err_msg();
12 changes: 8 additions & 4 deletions src/bindings/c/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
#include "openvino/core/except.hpp"
#include "openvino/openvino.hpp"

#define CATCH_IE_EXCEPTION(StatusCode, ExceptionType) \
catch (const InferenceEngine::ExceptionType&) { \
return ov_status_e::StatusCode; \
#define CATCH_IE_EXCEPTION(StatusCode, ExceptionType) \
catch (const InferenceEngine::ExceptionType& ex) { \
dup_last_err_msg(ex.what()); \
return ov_status_e::StatusCode; \
}

#define CATCH_OV_EXCEPTION(StatusCode, ExceptionType) \
catch (const ov::ExceptionType&) { \
catch (const ov::ExceptionType& ex) { \
dup_last_err_msg(ex.what()); \
return ov_status_e::StatusCode; \
}

Expand All @@ -41,6 +43,7 @@
CATCH_IE_EXCEPTION(NETWORK_NOT_READ, NetworkNotRead) \
CATCH_IE_EXCEPTION(INFER_CANCELLED, InferCancelled) \
catch (...) { \
dup_last_err_msg("An unknown exception occurred"); \
return ov_status_e::UNKNOW_EXCEPTION; \
}

Expand Down Expand Up @@ -224,3 +227,4 @@ struct mem_istream : virtual mem_stringbuf, std::istream {

char* str_to_char_array(const std::string& str);
ov::element::Type get_element_type(ov_element_type_e type);
void dup_last_err_msg(const char* msg);
20 changes: 20 additions & 0 deletions src/bindings/c/src/ov_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ char* str_to_char_array(const std::string& str) {
return char_array;
}

static std::string last_err_msg;
static std::mutex last_msg_mutex;
void dup_last_err_msg(const char* msg) {
std::lock_guard<std::mutex> lock(last_msg_mutex);
last_err_msg = std::string(msg);
}

const char* ov_get_last_err_msg() {
std::lock_guard<std::mutex> lock(last_msg_mutex);
char* res = nullptr;
if (!last_err_msg.empty()) {
res = str_to_char_array(last_err_msg);
}
return res;
}

ov_status_e ov_get_openvino_version(ov_version_t* version) {
if (!version) {
return ov_status_e::INVALID_C_PARAM;
Expand Down Expand Up @@ -66,6 +82,10 @@ ov_status_e ov_core_create(ov_core_t** core) {
void ov_core_free(ov_core_t* core) {
if (core)
delete core;

// release err msg buffer, there will be no err msg after core is freed.
std::lock_guard<std::mutex> lock(last_msg_mutex);
last_err_msg.clear();
}

ov_status_e ov_core_read_model(const ov_core_t* core,
Expand Down
34 changes: 34 additions & 0 deletions src/bindings/c/tests/ov_core_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ov_core_test : public ov_capi_test_base {
ov_capi_test_base::TearDown();
}
};

INSTANTIATE_TEST_SUITE_P(ov_core, ov_core_test, ::testing::Values("CPU"));

TEST_P(ov_core_test, ov_core_create_with_config) {
Expand Down Expand Up @@ -699,4 +700,37 @@ TEST_P(ov_core_test, ov_core_compile_model_from_file_unicode) {
}
#endif

using ov_util_test = ov_core_test;
INSTANTIATE_TEST_SUITE_P(ov_capi_test, ov_util_test, ::testing::Values("CPU"));

TEST_P(ov_util_test, ov_get_last_err_msg_check) {
auto device_name = GetParam();
ov_core_t* core = nullptr;
OV_EXPECT_OK(ov_core_create(&core));
EXPECT_NE(nullptr, core);

const char* key = ov_property_key_inference_num_threads;
OV_EXPECT_OK(ov_core_set_property(core, device_name.c_str(), key, "abc"));

char* ret = nullptr;
OV_EXPECT_NOT_OK(ov_core_get_property(core, device_name.c_str(), key, &ret));

auto err_msg = ov_get_last_err_msg();
EXPECT_NE(nullptr, err_msg);
ov_free(err_msg);
ov_free(ret);
ov_core_free(core);
}

TEST_P(ov_util_test, ov_get_last_err_msg_check_empty_msg) {
auto device_name = GetParam();
ov_core_t* core = nullptr;
OV_EXPECT_OK(ov_core_create(&core));
EXPECT_NE(nullptr, core);

auto err_msg = ov_get_last_err_msg();
EXPECT_EQ(nullptr, err_msg);
ov_core_free(core);
}

} // namespace
Loading