daemon: adopt HandlerResult<T> — real error codes from handlers (contracts/ 1.4.0)

Rebased onto main at 1.4.0. The regenerated Dispatcher returns
HandlerResult<T> = expected<T, HandlerError{code, message, data}>
(ADR 0014); the covariant-return break on all 39 overrides is the swap
predicted in daemon/docs/proto-requests-m1.md P1.

- dispatcher.hpp/.cpp: Result<T> -> HandlerResult<T> on every override;
  not_implemented() now returns HandlerError{InternalError, ...} rather
  than a ParseError forwarded as -32603.
- download.get: returns -32010 TaskNotFound with data.taskId. Not a
  placeholder — with no store, every id is genuinely not-found, which
  is the real answer for contracts/ fixture download.get.not-found. It
  becomes a store lookup when store/ is wired in.
- uds_roundtrip: the -32603-collapse guard is now a -32010 + data.taskId
  assertion, the regression guard the P1 note promised.

download.add (-32011) and download.probe (-32013) stay InternalError
until they have real bodies (canonicalization / probe); they get their
fixture codes when that logic lands.

All 24 tests green; uds_roundtrip TSan-clean.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Upd9WhG9oppieig5nRDLig
This commit is contained in:
2026-09-10 15:31:00 +04:00
co-authored by Claude Sonnet 5
parent 4b279e8271
commit e585113daf
3 changed files with 97 additions and 90 deletions
+7 -5
View File
@@ -148,17 +148,19 @@ void run() {
::close(c);
}
// --- download.get -> -32603 for now: documents the P1 codegen gap ---------------
// (proto-requests-m1.md P1: handlers cannot yet return -32010. When P1 lands this
// check flips to -32010 and is the regression guard for it.)
// --- download.get on an unknown id -> -32010, with data.taskId ------------------
// (contracts/ error fixture download.get.not-found; reachable now that 1.4.0 gave
// handlers the HandlerError channel — ADR 0014.)
{
const int c = connect_client(sock);
const std::string missing = "00000000-0000-4000-8000-000000000000";
const json reply = call(c, {{"jsonrpc", "2.0"},
{"id", 6},
{"method", "download.get"},
{"params", {{"taskId", "00000000-0000-4000-8000-000000000000"}}}});
{"params", {{"taskId", missing}}}});
CHECK(reply.contains("error"));
CHECK_EQ(reply["error"]["code"].get<int>(), -32603);
CHECK_EQ(reply["error"]["code"].get<int>(), -32010);
CHECK_EQ(reply["error"]["data"]["taskId"].get<std::string>(), missing);
::close(c);
}