From 6f8ed224ef0b16afe75ff5fdda1a0916d33a3fb9 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Thu, 6 Nov 2025 12:29:32 -0800 Subject: [PATCH 1/2] dispatch lambdas into error handler --- bindings/cpp/src/svs_runtime_utils.h | 21 +++++++++++++++++++++ bindings/cpp/src/training.cpp | 23 +++++++++-------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/bindings/cpp/src/svs_runtime_utils.h b/bindings/cpp/src/svs_runtime_utils.h index ef8e4ace..996f2104 100644 --- a/bindings/cpp/src/svs_runtime_utils.h +++ b/bindings/cpp/src/svs_runtime_utils.h @@ -21,7 +21,10 @@ // TODO remove unused includes #include +#include +#include #include +#include #include #include @@ -83,6 +86,24 @@ class StatusException : public svs::lib::ANNException { ); \ } +template +inline auto safe_runtime_call(Callable&& func) noexcept -> Status { + try { + func(); + return Status_Ok; + } catch (const svs::runtime::StatusException& ex) { + return Status(ex.code(), ex.what()); + } catch (const std::invalid_argument& ex) { + return Status(ErrorCode::INVALID_ARGUMENT, ex.what()); + } catch (const std::runtime_error& ex) { + return Status(ErrorCode::RUNTIME_ERROR, ex.what()); + } catch (const std::exception& ex) { + return Status(ErrorCode::UNKNOWN_ERROR, ex.what()); + } catch (...) { + return Status(ErrorCode::UNKNOWN_ERROR, "An unknown error has occurred."); + } +} + using LeanVecMatricesType = svs::leanvec::LeanVecMatrices; namespace storage { diff --git a/bindings/cpp/src/training.cpp b/bindings/cpp/src/training.cpp index a6680b2d..8f5af943 100644 --- a/bindings/cpp/src/training.cpp +++ b/bindings/cpp/src/training.cpp @@ -28,27 +28,22 @@ Status LeanVecTrainingData::build( const float* x, size_t leanvec_dims ) noexcept { - SVS_RUNTIME_TRY_BEGIN - const auto data = svs::data::ConstSimpleDataView(x, n, dim); - *training_data = - new LeanVecTrainingDataManager{LeanVecTrainingDataImpl{data, leanvec_dims}}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return safe_runtime_call([&] { + const auto data = svs::data::ConstSimpleDataView(x, n, dim); + *training_data = + new LeanVecTrainingDataManager{LeanVecTrainingDataImpl{data, leanvec_dims}}; + }); } Status LeanVecTrainingData::destroy(LeanVecTrainingData* training_data) noexcept { - SVS_RUNTIME_TRY_BEGIN - delete training_data; - return Status_Ok; - SVS_RUNTIME_TRY_END + return safe_runtime_call([&] { delete training_data; }); } Status LeanVecTrainingData::load(LeanVecTrainingData** training_data, std::istream& in) noexcept { - SVS_RUNTIME_TRY_BEGIN - *training_data = new LeanVecTrainingDataManager{LeanVecTrainingDataImpl::load(in)}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return safe_runtime_call([&] { + *training_data = new LeanVecTrainingDataManager{LeanVecTrainingDataImpl::load(in)}; + }); } } // namespace runtime } // namespace svs From aaa22c95eae7703931ad012cbf3c5e89e3dbae72 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 7 Nov 2025 00:02:54 -0800 Subject: [PATCH 2/2] consistently use runtime_error_wrapper() --- bindings/cpp/src/dynamic_vamana_index.cpp | 118 +++++++++------------- bindings/cpp/src/svs_runtime_utils.h | 23 +---- bindings/cpp/src/training.cpp | 6 +- bindings/cpp/src/training_impl.h | 5 +- 4 files changed, 55 insertions(+), 97 deletions(-) diff --git a/bindings/cpp/src/dynamic_vamana_index.cpp b/bindings/cpp/src/dynamic_vamana_index.cpp index 3d7ae894..fa58cea9 100644 --- a/bindings/cpp/src/dynamic_vamana_index.cpp +++ b/bindings/cpp/src/dynamic_vamana_index.cpp @@ -55,28 +55,25 @@ struct DynamicVamanaIndexManagerBase : public DynamicVamanaIndex { ~DynamicVamanaIndexManagerBase() override = default; Status add(size_t n, const size_t* labels, const float* x) noexcept override { - SVS_RUNTIME_TRY_BEGIN - svs::data::ConstSimpleDataView data{x, n, impl_->dimensions()}; - std::span lbls(labels, n); - impl_->add(data, lbls); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + svs::data::ConstSimpleDataView data{x, n, impl_->dimensions()}; + std::span lbls(labels, n); + impl_->add(data, lbls); + }); } Status remove_selected(size_t* num_removed, const IDFilter& selector) noexcept override { - SVS_RUNTIME_TRY_BEGIN - *num_removed = impl_->remove_selected(selector); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + *num_removed = impl_->remove_selected(selector); + }); } Status remove(size_t n, const size_t* labels) noexcept override { - SVS_RUNTIME_TRY_BEGIN - std::span lbls(labels, n); - impl_->remove(lbls); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + std::span lbls(labels, n); + impl_->remove(lbls); + }); } Status search( @@ -88,12 +85,11 @@ struct DynamicVamanaIndexManagerBase : public DynamicVamanaIndex { const SearchParams* params = nullptr, IDFilter* filter = nullptr ) const noexcept override { - SVS_RUNTIME_TRY_BEGIN - // TODO wrap arguments into proper data structures in DynamicVamanaIndexImpl and - // here - impl_->search(n, x, k, distances, labels, params, filter); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + // TODO wrap arguments into proper data structures in DynamicVamanaIndexImpl and + // here + impl_->search(n, x, k, distances, labels, params, filter); + }); } Status range_search( @@ -104,26 +100,19 @@ struct DynamicVamanaIndexManagerBase : public DynamicVamanaIndex { const SearchParams* params = nullptr, IDFilter* filter = nullptr ) const noexcept override { - SVS_RUNTIME_TRY_BEGIN - // TODO wrap arguments into proper data structures in DynamicVamanaIndexImpl and - // here - impl_->range_search(n, x, radius, results, params, filter); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + // TODO wrap arguments into proper data structures in DynamicVamanaIndexImpl and + // here + impl_->range_search(n, x, radius, results, params, filter); + }); } Status reset() noexcept override { - SVS_RUNTIME_TRY_BEGIN - impl_->reset(); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { impl_->reset(); }); } Status save(std::ostream& out) const noexcept override { - SVS_RUNTIME_TRY_BEGIN - impl_->save(out); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { impl_->save(out); }); } }; @@ -142,20 +131,16 @@ Status DynamicVamanaIndex::build( const DynamicVamanaIndex::SearchParams& default_search_params ) noexcept { *index = nullptr; - SVS_RUNTIME_TRY_BEGIN - auto impl = std::make_unique( - dim, metric, storage_kind, params, default_search_params - ); - *index = new DynamicVamanaIndexManager{std::move(impl)}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + auto impl = std::make_unique( + dim, metric, storage_kind, params, default_search_params + ); + *index = new DynamicVamanaIndexManager{std::move(impl)}; + }); } Status DynamicVamanaIndex::destroy(DynamicVamanaIndex* index) noexcept { - SVS_RUNTIME_TRY_BEGIN - delete index; - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { delete index; }); } Status DynamicVamanaIndex::load( @@ -165,12 +150,11 @@ Status DynamicVamanaIndex::load( StorageKind storage_kind ) noexcept { *index = nullptr; - SVS_RUNTIME_TRY_BEGIN - std::unique_ptr impl{ - DynamicVamanaIndexImpl::load(in, metric, storage_kind)}; - *index = new DynamicVamanaIndexManager{std::move(impl)}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + std::unique_ptr impl{ + DynamicVamanaIndexImpl::load(in, metric, storage_kind)}; + *index = new DynamicVamanaIndexManager{std::move(impl)}; + }); } // Specialization to build LeanVec-based Vamana index with specified leanvec dims @@ -184,13 +168,12 @@ Status DynamicVamanaIndexLeanVec::build( const DynamicVamanaIndex::SearchParams& default_search_params ) noexcept { *index = nullptr; - SVS_RUNTIME_TRY_BEGIN - auto impl = std::make_unique( - dim, metric, storage_kind, leanvec_dims, params, default_search_params - ); - *index = new DynamicVamanaIndexLeanVecImplManager{std::move(impl)}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + auto impl = std::make_unique( + dim, metric, storage_kind, leanvec_dims, params, default_search_params + ); + *index = new DynamicVamanaIndexLeanVecImplManager{std::move(impl)}; + }); } // Specialization to build LeanVec-based Vamana index with provided training data @@ -204,15 +187,14 @@ Status DynamicVamanaIndexLeanVec::build( const DynamicVamanaIndex::SearchParams& default_search_params ) noexcept { *index = nullptr; - SVS_RUNTIME_TRY_BEGIN - auto training_data_impl = - static_cast(training_data)->impl_; - auto impl = std::make_unique( - dim, metric, storage_kind, training_data_impl, params, default_search_params - ); - *index = new DynamicVamanaIndexLeanVecImplManager{std::move(impl)}; - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { + auto training_data_impl = + static_cast(training_data)->impl_; + auto impl = std::make_unique( + dim, metric, storage_kind, training_data_impl, params, default_search_params + ); + *index = new DynamicVamanaIndexLeanVecImplManager{std::move(impl)}; + }); } } // namespace runtime diff --git a/bindings/cpp/src/svs_runtime_utils.h b/bindings/cpp/src/svs_runtime_utils.h index 996f2104..24ba188d 100644 --- a/bindings/cpp/src/svs_runtime_utils.h +++ b/bindings/cpp/src/svs_runtime_utils.h @@ -65,29 +65,8 @@ class StatusException : public svs::lib::ANNException { svs::runtime::ErrorCode errcode_; }; -#define SVS_RUNTIME_TRY_BEGIN try { -#define SVS_RUNTIME_TRY_END \ - } \ - catch (const svs::runtime::StatusException& ex) { \ - return svs::runtime::Status(ex.code(), ex.what()); \ - } \ - catch (const std::invalid_argument& ex) { \ - return svs::runtime::Status(svs::runtime::ErrorCode::INVALID_ARGUMENT, ex.what()); \ - } \ - catch (const std::runtime_error& ex) { \ - return svs::runtime::Status(svs::runtime::ErrorCode::RUNTIME_ERROR, ex.what()); \ - } \ - catch (const std::exception& ex) { \ - return svs::runtime::Status(svs::runtime::ErrorCode::UNKNOWN_ERROR, ex.what()); \ - } \ - catch (...) { \ - return svs::runtime::Status( \ - svs::runtime::ErrorCode::UNKNOWN_ERROR, "An unknown error has occurred." \ - ); \ - } - template -inline auto safe_runtime_call(Callable&& func) noexcept -> Status { +inline auto runtime_error_wrapper(Callable&& func) noexcept -> Status { try { func(); return Status_Ok; diff --git a/bindings/cpp/src/training.cpp b/bindings/cpp/src/training.cpp index 8f5af943..1e49f5a8 100644 --- a/bindings/cpp/src/training.cpp +++ b/bindings/cpp/src/training.cpp @@ -28,7 +28,7 @@ Status LeanVecTrainingData::build( const float* x, size_t leanvec_dims ) noexcept { - return safe_runtime_call([&] { + return runtime_error_wrapper([&] { const auto data = svs::data::ConstSimpleDataView(x, n, dim); *training_data = new LeanVecTrainingDataManager{LeanVecTrainingDataImpl{data, leanvec_dims}}; @@ -36,12 +36,12 @@ Status LeanVecTrainingData::build( } Status LeanVecTrainingData::destroy(LeanVecTrainingData* training_data) noexcept { - return safe_runtime_call([&] { delete training_data; }); + return runtime_error_wrapper([&] { delete training_data; }); } Status LeanVecTrainingData::load(LeanVecTrainingData** training_data, std::istream& in) noexcept { - return safe_runtime_call([&] { + return runtime_error_wrapper([&] { *training_data = new LeanVecTrainingDataManager{LeanVecTrainingDataImpl::load(in)}; }); } diff --git a/bindings/cpp/src/training_impl.h b/bindings/cpp/src/training_impl.h index fdc54d49..f8ed77a4 100644 --- a/bindings/cpp/src/training_impl.h +++ b/bindings/cpp/src/training_impl.h @@ -84,10 +84,7 @@ struct LeanVecTrainingDataManager : public svs::runtime::LeanVecTrainingData { : impl_{std::move(impl)} {} Status save(std::ostream& out) const noexcept override { - SVS_RUNTIME_TRY_BEGIN - impl_.save(out); - return Status_Ok; - SVS_RUNTIME_TRY_END + return runtime_error_wrapper([&] { impl_.save(out); }); } LeanVecTrainingDataImpl impl_;