diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h @@ -24,6 +24,8 @@ std::unique_ptr networkClient; + template + T runSyncOrThrowJSError(jsi::Runtime &rt, std::function task); jsi::Value getDraft(jsi::Runtime &rt, const jsi::String &key) override; jsi::Value updateDraft(jsi::Runtime &rt, const jsi::Object &draft) override; jsi::Value moveDraft( diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp @@ -18,6 +18,28 @@ using namespace facebook::react; +template +T CommCoreModule::runSyncOrThrowJSError( + jsi::Runtime &rt, + std::function task) { + std::promise promise; + this->databaseThread->scheduleTask([&promise, &task]() { + try { + promise.set_value(task()); + } catch (const std::exception &e) { + promise.set_exception(std::make_exception_ptr(e)); + } + }); + // We cannot instantiate JSError on database thread, so + // on the main thread we re-throw C++ error, catch it and + // transform to informative JSError on the main thread + try { + return promise.get_future().get(); + } catch (const std::exception &e) { + throw jsi::JSError(rt, e.what()); + } +} + jsi::Value CommCoreModule::getDraft(jsi::Runtime &rt, const jsi::String &key) { std::string keyStr = key.utf8(rt); return createPromiseAsJSIValue( @@ -161,16 +183,10 @@ } jsi::Array CommCoreModule::getAllMessagesSync(jsi::Runtime &rt) { - std::promise>>> - messagesResult; - auto messagesResultFuture = messagesResult.get_future(); - - this->databaseThread->scheduleTask([&messagesResult]() { - messagesResult.set_value( - DatabaseManager::getQueryExecutor().getAllMessages()); + auto messagesVector = this->runSyncOrThrowJSError< + std::vector>>>(rt, []() { + return DatabaseManager::getQueryExecutor().getAllMessages(); }); - - auto messagesVector = messagesResultFuture.get(); size_t numMessages{messagesVector.size()}; jsi::Array jsiMessages = jsi::Array(rt, numMessages); @@ -510,15 +526,8 @@ }; jsi::Array CommCoreModule::getAllThreadsSync(jsi::Runtime &rt) { - std::promise> threadsResult; - auto threadsResultFuture = threadsResult.get_future(); - - this->databaseThread->scheduleTask([&threadsResult]() { - threadsResult.set_value( - DatabaseManager::getQueryExecutor().getAllThreads()); - }); - - auto threadsVector = threadsResultFuture.get(); + auto threadsVector = this->runSyncOrThrowJSError>( + rt, []() { return DatabaseManager::getQueryExecutor().getAllThreads(); }); size_t numThreads{threadsVector.size()}; jsi::Array jsiThreads = jsi::Array(rt, numThreads);