Duncan Tourolle c39db82763
All checks were successful
🧪 Test / test (push) Successful in 6m7s
Add a per node error handler possibility
2026-05-10 19:51:23 +02:00

74 lines
2.2 KiB
C++

// Example 15 — Per-node Error Handler
//
// Demonstrates set_error_handler() for deciding whether a network can
// continue when a node throws an exception.
//
// The "validator" node rejects even numbers by throwing std::runtime_error.
// Its error handler logs the failure and returns true (skip & continue),
// so odd numbers still flow through to the sink.
//
// Compare: a second handler (commented below) returns false instead,
// which stops the node and gracefully shuts the downstream side down.
//
// Pipeline: [source] --int--> [validator] --int--> [sink]
#include <kpn/kpn.hpp>
#include <chrono>
#include <iostream>
#include <thread>
static int counter = 0;
static int source() {
std::this_thread::sleep_for(std::chrono::milliseconds(20));
return ++counter;
}
static int validate(int x) {
if (x % 2 == 0)
throw std::runtime_error("even number rejected: " + std::to_string(x));
return x;
}
static int received = 0;
static void sink(int x) {
std::cout << " processed: " << x << '\n';
++received;
}
int main() {
using namespace kpn;
auto src = make_node<source> ();
auto proc = make_node<validate>();
auto snk = make_node<sink> ();
// Return true → skip this invocation, keep the node running.
// Return false → stop the node (downstream drains then also stops).
proc.set_error_handler([](std::string_view name, std::exception_ptr ep) {
try { std::rethrow_exception(ep); }
catch (const std::exception& e) {
std::cerr << "[" << name << "] skipping item — " << e.what() << '\n';
}
return true;
});
Network net;
net.add("source", src)
.add("validator", proc)
.add("sink", snk)
.connect("source", src.output<0>(), "validator", proc.input<0>())
.connect("validator", proc.output<0>(), "sink", snk.input<0>())
.build();
std::cout << "source emits 1..N; validator rejects even numbers.\n"
<< "Error messages on stderr, accepted items on stdout.\n\n";
net.start();
std::this_thread::sleep_for(std::chrono::milliseconds(300));
net.stop();
std::cout << "\nItems accepted by sink: " << received << '\n';
}