From 8713bbca12b846750b3177751f2e96d1aeb68265 Mon Sep 17 00:00:00 2001 From: chenshi5012 <10794822+chenshi5012@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:54:15 +0000 Subject: [PATCH] Return SessionPool session after JSON errors --- src/client/SessionPool.cpp | 28 +++++++++++------- src/client/tests/SessionPoolTest.cpp | 43 +++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/client/SessionPool.cpp b/src/client/SessionPool.cpp index 3c8396c1..f069b846 100644 --- a/src/client/SessionPool.cpp +++ b/src/client/SessionPool.cpp @@ -77,18 +77,24 @@ std::string SessionPool::executeJsonWithParameter( const std::string &stmt, const std::unordered_map ¶meters) { auto result = getIdleSession(); if (result.second) { - auto resp = result.first.executeJsonWithParameter(stmt, parameters); - auto obj = folly::parseJson(resp); - auto respSpaceName = obj["results"][0]["spaceName"].asString(); - if (respSpaceName != config_.spaceName_) { - if (respSpaceName == "") { - // This can be caused by reconnect, switch to origin space and try to query again - resp = result.first.executeJsonWithParameter("USE " + config_.spaceName_ + ";" + stmt, - parameters); - } else { - // switch to origin space only - result.first.execute("USE " + config_.spaceName_); + std::string resp; + try { + resp = result.first.executeJsonWithParameter(stmt, parameters); + auto obj = folly::parseJson(resp); + auto respSpaceName = obj["results"][0]["spaceName"].asString(); + if (respSpaceName != config_.spaceName_) { + if (respSpaceName == "") { + // This can be caused by reconnect, switch to origin space and try to query again + resp = result.first.executeJsonWithParameter("USE " + config_.spaceName_ + ";" + stmt, + parameters); + } else { + // switch to origin space only + result.first.execute("USE " + config_.spaceName_); + } } + } catch (...) { + giveBack(std::move(result.first)); + throw; } giveBack(std::move(result.first)); return resp; diff --git a/src/client/tests/SessionPoolTest.cpp b/src/client/tests/SessionPoolTest.cpp index fe2105ce..bb6720ce 100644 --- a/src/client/tests/SessionPoolTest.cpp +++ b/src/client/tests/SessionPoolTest.cpp @@ -3,17 +3,36 @@ // This source code is licensed under Apache 2.0 License. #include +#include #include #include #include #include #include #include -#include +#include +#include #include +#include #include +#include +#include +#include +#include #include +#include +#include + +#define private public +#include +#undef private + +#include + +#define private public +#include +#undef private #include "./ClientTest.h" @@ -154,6 +173,28 @@ TEST_F(SessionPoolTest, Normal) { } } +TEST_F(SessionPoolTest, JsonParseFailureReturnsSessionToPool) { + nebula::SessionPoolConfig config; + config.username_ = "root"; + config.password_ = "nebula"; + config.addrs_ = {kServerHost ":9669"}; + config.spaceName_ = "session_pool_test"; + config.maxSize_ = 1; + + nebula::SessionPool pool(config); + ASSERT_TRUE(pool.init()); + ASSERT_EQ(pool.idleSessions_.size(), 1); + + // Force Connection::executeJsonWithParameter() to return an empty response. + pool.idleSessions_.front().conn_.close(); + EXPECT_THROW(pool.executeJson("YIELD 1"), std::exception); + ASSERT_EQ(pool.idleSessions_.size(), 1); + + auto resp = pool.execute("YIELD 1"); + EXPECT_NE(resp.errorMsg ? *resp.errorMsg : "", "No idle session."); + EXPECT_EQ(pool.idleSessions_.size(), 1); +} + // case 3 TEST_F(SessionPoolTest, SwitchSpace) { nebula::SessionPoolConfig config;