Summary
MainThreadExecutor::runTask catches only const std::exception&. Its sibling ThreadPoolExecutor::loop catches that and .... Three doc comments on the MainThreadExecutor side promise the behaviour only the pool actually implements.
Verification status
Verified by reading; not reproduced. Revision: origin/master adfe8e5f plus this branch's doc-only commits.
include/morph/core/executor.hpp:211-217:
void runTask(std::function<void()> task) {
try { task(); }
catch (const std::exception& exc) { ::morph::log::logError("[main-thread] callback threw: " + …); }
}
include/morph/core/executor.hpp:105-113 (the pool):
try { task(); }
catch (const std::exception& exc) { ::morph::log::logError("[thread-pool] task threw: " + …); }
catch (...) { ::morph::log::logError("[thread-pool] task threw unknown exception"); }
The three claims it breaks
:147-149 (runFor) — "Exceptions thrown by tasks are logged and execution continues with the next task." A non-std::exception unwinds out of runFor, abandoning the rest of the pump window.
:171-172 (runOnce) — "pops exactly one task, runs it, and returns true whether or not that task threw". The function does not return at all in that case.
:194-201 (drain) — inherits the same, and leaves the queue undrained.
The asymmetry between two executors in the same header, with the pool's catch (...) carrying its own deliberate log message, reads as an oversight rather than a policy difference.
What would change the verdict
- Close it if letting a non-
std::exception escape the GUI pump is deliberate (e.g. so it reaches Qt's handler) — in which case the three doc comments need correcting instead, and the divergence from ThreadPoolExecutor deserves a sentence.
- Fix is one
catch (...) arm mirroring the pool's.
Summary
MainThreadExecutor::runTaskcatches onlyconst std::exception&. Its siblingThreadPoolExecutor::loopcatches that and.... Three doc comments on theMainThreadExecutorside promise the behaviour only the pool actually implements.Verification status
Verified by reading; not reproduced. Revision:
origin/masteradfe8e5fplus this branch's doc-only commits.include/morph/core/executor.hpp:211-217:include/morph/core/executor.hpp:105-113(the pool):The three claims it breaks
:147-149(runFor) — "Exceptions thrown by tasks are logged and execution continues with the next task." A non-std::exceptionunwinds out ofrunFor, abandoning the rest of the pump window.:171-172(runOnce) — "pops exactly one task, runs it, and returnstruewhether or not that task threw". The function does not return at all in that case.:194-201(drain) — inherits the same, and leaves the queue undrained.The asymmetry between two executors in the same header, with the pool's
catch (...)carrying its own deliberate log message, reads as an oversight rather than a policy difference.What would change the verdict
std::exceptionescape the GUI pump is deliberate (e.g. so it reaches Qt's handler) — in which case the three doc comments need correcting instead, and the divergence fromThreadPoolExecutordeserves a sentence.catch (...)arm mirroring the pool's.