2.6 KiB
Error Handling & Events
KPN++ provides three complementary layers for observing and reacting to failures.
1. Per-node error handler
Called when a node's function throws an unhandled exception. Return true to skip the failed invocation and keep running; false to stop the node.
--8<-- "examples/15_node_error_handler/main.cpp:error_handler"
When a node stops (either from false return or no handler installed), it:
- Disables its input channels — upstream stops pushing into dead queues.
- Disables its output channels — downstream nodes receive
ChannelClosedErroron their next pop, propagating the shutdown naturally through the graph.
2. Per-node overflow callback
Fired with a timestamp each time an output push is dropped because the channel is full. The node name is known at registration so it is not included — keeping the callback zero-overhead when unused.
--8<-- "examples/16_event_callbacks/main.cpp:per_node_callback"
!!! note
The callback is purely informational — the node always continues after an overflow. To stop the node on overflow, call node.stop() from inside the callback.
A matching set_closed_callback() fires (also with just a timestamp) when the node stops due to a closed upstream channel:
node.set_closed_callback([](std::chrono::steady_clock::time_point ts) {
std::cerr << "node stopped at t=" << ts.time_since_epoch().count() << '\n';
});
Each node holds two callback slots per event type — one user-set (registered above) and one injected by the network (see below). Both fire independently.
3. Network-level event handler
One callback for the whole network. Receives the node name (captured in a closure by the network at build() / start()), a NodeEvent, and a timestamp:
--8<-- "examples/16_event_callbacks/main.cpp:network_event_handler"
NodeEvent values:
| Value | Meaning |
|---|---|
NodeEvent::Overflow |
An output push was dropped (channel full) |
NodeEvent::Closed |
The node stopped (crash or upstream close cascade) |
The network handler and any per-node callbacks are independent — both fire when set.
Complete example
examples/16_event_callbacks/main.cpp shows a fast producer overflowing a slow consumer, with both a per-node overflow callback and a network-level event handler active simultaneously.
Node functions:
--8<-- "examples/16_event_callbacks/main.cpp:node_fns"
Per-node overflow callback:
--8<-- "examples/16_event_callbacks/main.cpp:per_node_callback"
Network-level event handler:
--8<-- "examples/16_event_callbacks/main.cpp:network_event_handler"