From 122df11433934f422b1afd1b81e5bfaa36379a05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=CE=A7=CE=B3=CF=86=CF=84=20Kompanion?=
 <chigammaphitau@chelydra.at>
Date: Wed, 15 Oct 2025 18:53:01 +0200
Subject: [PATCH] memory: remove exception parsing helpers

---
 src/mcp/HandlersMemory.hpp | 63 +++++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 21 deletions(-)

diff --git a/src/mcp/HandlersMemory.hpp b/src/mcp/HandlersMemory.hpp
index a56fa12..ea45e9b 100644
--- a/src/mcp/HandlersMemory.hpp
+++ b/src/mcp/HandlersMemory.hpp
@@ -1,10 +1,12 @@
 #pragma once
 
 #include <algorithm>
+#include <charconv>
 #include <chrono>
 #include <cctype>
 #include <cstdlib>
 #include <ctime>
+#include <exception>
 #include <iomanip>
 #include <optional>
 #include <sstream>
@@ -190,11 +192,13 @@ inline std::optional<int> extract_int_field(const std::string& json, const std::
     std::size_t start = pos;
     while (pos < json.size() && (std::isdigit(static_cast<unsigned char>(json[pos])) || json[pos] == '-')) ++pos;
     if (start == pos) return std::nullopt;
-    try {
-        return std::stoi(json.substr(start, pos - start));
-    } catch (...) {
+    const std::string_view token{json.data() + start, pos - start};
+    int value = 0;
+    const auto parseResult = std::from_chars(token.data(), token.data() + token.size(), value);
+    if (parseResult.ec != std::errc() || parseResult.ptr != token.data() + token.size()) {
         return std::nullopt;
     }
+    return value;
 }
 
 inline std::string iso8601_from_tp(std::chrono::system_clock::time_point tp) {
@@ -299,10 +303,12 @@ inline std::vector<float> parse_float_array(const std::string& json, const std::
         if (pos >= arr.size()) break;
         std::size_t end = pos;
         while (end < arr.size() && (std::isdigit(static_cast<unsigned char>(arr[end])) || arr[end] == '.' || arr[end] == 'e' || arr[end] == 'E' || arr[end] == '+' || arr[end] == '-')) ++end;
-        try {
-            values.push_back(std::stof(arr.substr(pos, end - pos)));
-        } catch (...) {
-            // Skip unparsable token.
+        float parsed = 0.0f;
+        const char* begin = arr.c_str() + pos;
+        const char* finish = arr.c_str() + end;
+        const auto fc = std::from_chars(begin, finish, parsed);
+        if (fc.ec == std::errc() && fc.ptr == finish) {
+            values.push_back(parsed);
         }
         pos = end;
     }
@@ -384,7 +390,9 @@ inline std::string upsert_memory(const std::string& reqJson) {
     std::vector<std::string> ids;
     ids.reserve(items.size());
 
+#if defined(__cpp_exceptions)
     try {
+#endif
         for (auto& parsed : items) {
             kom::ItemRow row;
             row.id = parsed.id;
@@ -412,11 +420,14 @@ inline std::string upsert_memory(const std::string& reqJson) {
                 dal.upsertEmbeddings(std::vector<kom::EmbeddingRow>{emb});
             }
         }
-        if (hasTx) dal.commit();
+#if defined(__cpp_exceptions)
     } catch (const std::exception& ex) {
         if (hasTx) dal.rollback();
         return detail::error_response("internal_error", ex.what());
     }
+#endif
+
+    if (hasTx) dal.commit();
 
     std::ostringstream os;
     os << "{\"upserted\":" << ids.size();
@@ -530,23 +541,33 @@ inline std::string save_context(const std::string& reqJson) {
         }
     }
 
+    std::string insertedId;
+#if defined(__cpp_exceptions)
     try {
-        const std::string id = dal.upsertItem(row);
-        auto stored = dal.getItemById(id);
-        const auto createdTp = stored ? stored->created_at : row.created_at;
-        std::string createdIso = detail::iso8601_from_tp(createdTp);
-        if (createdIso.empty()) {
-            createdIso = detail::iso8601_from_tp(std::chrono::system_clock::now());
-        }
-
-        std::ostringstream os;
-        os << "{\"id\":\"" << detail::json_escape(id) << "\"";
-        os << ",\"created_at\":\"" << createdIso << "\"";
-        os << "}";
-        return os.str();
+#endif
+        insertedId = dal.upsertItem(row);
+#if defined(__cpp_exceptions)
     } catch (const std::exception& ex) {
         return detail::error_response("internal_error", ex.what());
     }
+#endif
+
+    if (insertedId.empty()) {
+        return detail::error_response("internal_error", "failed to upsert item");
+    }
+
+    auto stored = dal.getItemById(insertedId);
+    const auto createdTp = stored ? stored->created_at : row.created_at;
+    std::string createdIso = detail::iso8601_from_tp(createdTp);
+    if (createdIso.empty()) {
+        createdIso = detail::iso8601_from_tp(std::chrono::system_clock::now());
+    }
+
+    std::ostringstream os;
+    os << "{\"id\":\"" << detail::json_escape(insertedId) << "\"";
+    os << ",\"created_at\":\"" << createdIso << "\"";
+    os << "}";
+    return os.str();
 }
 
 inline std::string recall_context(const std::string& reqJson) {
