What would you like?
Make fallible operations report failure to the caller — via std::expected<void, ErrorCode>
(or a returned status enum) — instead of logging an error and returning void, so callers and
the GUI can react to failures.
Use case / motivation
Several mutators validate, log on failure, and silently return:
// src/elements/element.cpp:43-77
void Element::addInput(const std::shared_ptr<Element>& inputElement, const std::string& inputComponent)
{
if (!inputElement) { log(LogLevel::ERROR, "Input is null."); return; } // caller can't tell
...
if (sizes mismatch) { log(LogLevel::ERROR, "...different size..."); return; }
}
When a user wires two incompatible elements in the node graph, the connection silently doesn't
happen and the only feedback is a line in the log window. The same pattern appears in
removeInput, createInteraction, and parts of file load. There's a well-structured
ErrorCode enum (include/exceptions/exception.h) already available to describe failures.
What's missing today?
No std::expected/std::optional on these APIs; success/failure isn't observable at the call
site. Error handling is split between exceptions (for "hard" errors) and log-and-continue (for
wiring/validation), inconsistently.
Possible approach
- Change the fallible mutators to return
std::expected<void, ErrorCode> (C++23; available on
the toolchains in use — GCC 13 / recent Clang / MSVC; verify and gate if needed) or, if
C++23 <expected> isn't acceptable yet, return the existing ErrorCode enum.
- Keep logging for diagnostics, but let callers branch on the result. Update the node-graph
connection code to surface a user-visible message / reject the link when addInput fails.
- Roll out incrementally (one API at a time), keeping behavior backward-compatible where
callers ignore the result ([[nodiscard]] encourages handling).
Verifiable end state: addInput/removeInput/createInteraction (at minimum) return a
typed result; the node-graph UI reacts to failed connections instead of silently dropping them;
existing tests updated. Higher-risk Phase 3 item — stage per-API.
What would you like?
Make fallible operations report failure to the caller — via
std::expected<void, ErrorCode>(or a returned status enum) — instead of logging an error and returning
void, so callers andthe GUI can react to failures.
Use case / motivation
Several mutators validate, log on failure, and silently
return:When a user wires two incompatible elements in the node graph, the connection silently doesn't
happen and the only feedback is a line in the log window. The same pattern appears in
removeInput,createInteraction, and parts of file load. There's a well-structuredErrorCodeenum (include/exceptions/exception.h) already available to describe failures.What's missing today?
No
std::expected/std::optionalon these APIs; success/failure isn't observable at the callsite. Error handling is split between exceptions (for "hard" errors) and log-and-continue (for
wiring/validation), inconsistently.
Possible approach
std::expected<void, ErrorCode>(C++23; available onthe toolchains in use — GCC 13 / recent Clang / MSVC; verify and gate if needed) or, if
C++23
<expected>isn't acceptable yet, return the existingErrorCodeenum.connection code to surface a user-visible message / reject the link when
addInputfails.callers ignore the result (
[[nodiscard]]encourages handling).Verifiable end state:
addInput/removeInput/createInteraction(at minimum) return atyped result; the node-graph UI reacts to failed connections instead of silently dropping them;
existing tests updated. Higher-risk Phase 3 item — stage per-API.