Add a per node error handler possibility
🧪 Test / test (push) Successful in 6m7s

This commit is contained in:
2026-05-10 19:51:23 +02:00
parent 1e9ba5ee66
commit c39db82763
4 changed files with 197 additions and 0 deletions
+21
View File
@@ -9,6 +9,7 @@
#include <atomic>
#include <chrono>
#include <cstddef>
#include <functional>
#include <iostream>
#include <memory>
#include <stdexcept>
@@ -18,6 +19,10 @@
namespace kpn {
// Called when a node's function throws. Return true to skip the failed
// invocation and keep running, false to stop the node.
using NodeErrorHandler = std::function<bool(std::string_view node_name, std::exception_ptr)>;
// ── INode — type-erased interface for Network / watchdog ─────────────────────
struct INode {
@@ -99,6 +104,8 @@ public:
void set_name(std::string name) override { name_ = std::move(name); }
void set_error_handler(NodeErrorHandler h) { error_handler_ = std::move(h); }
const NodeStats& stats() const override { return stats_; }
NodeSnapshot node_snapshot(const std::string& name, double elapsed_s) const override {
@@ -230,8 +237,13 @@ private:
break;
} catch (const ChannelOverflowError& e) {
std::cerr << "[kpn] overflow: " << e.what() << "\n";
} catch (...) {
if (error_handler_ && error_handler_(name_, std::current_exception()))
continue;
break;
}
}
stop_flag_.store(true, std::memory_order_relaxed);
}
// Pop all inputs into a tuple of argument values
@@ -287,6 +299,7 @@ private:
std::atomic<bool> stop_flag_{false};
std::jthread thread_;
NodeStats stats_;
NodeErrorHandler error_handler_;
};
// ── ObjectNode — wraps a callable object (functor / class with operator()) ────
@@ -357,6 +370,8 @@ public:
void set_name(std::string name) override { name_ = std::move(name); }
void set_error_handler(NodeErrorHandler h) { error_handler_ = std::move(h); }
const NodeStats& stats() const override { return stats_; }
NodeSnapshot node_snapshot(const std::string& name, double elapsed_s) const override {
@@ -474,8 +489,13 @@ private:
break;
} catch (const ChannelOverflowError& e) {
std::cerr << "[kpn] overflow: " << e.what() << "\n";
} catch (...) {
if (error_handler_ && error_handler_(name_, std::current_exception()))
continue;
break;
}
}
stop_flag_.store(true, std::memory_order_relaxed);
}
template<std::size_t... Is>
@@ -523,6 +543,7 @@ private:
std::atomic<bool> stop_flag_{false};
std::jthread thread_;
NodeStats stats_;
NodeErrorHandler error_handler_;
};
// ── make_node overloads for callable objects ──────────────────────────────────