A refused tool subscription is said, never fatal (novox/hq issue 218)

After the controller stopped granting a mesh seat to claimants that do not hold it, an image built
before the runtime followed its membership still subscribed the seat's subject, and the refusal
ended the process: ace's postgres runtime crash-looped. A subject the grants leave out now costs
that subject only, as an announcement's already did (issue 217).
This commit is contained in:
jochen
2026-10-04 00:13:15 +02:00
parent 7b21440962
commit 6604d44372
3 changed files with 52 additions and 11 deletions
+20 -10
View File
@@ -277,17 +277,27 @@ export async function connectNats(
const sub = conn.subscribe(subject, queue ? { queue } : {});
subs.push(sub);
void (async () => {
for await (const msg of sub) {
let reply: { result?: Res; error?: string; node?: string };
try {
reply = { result: await handler(JSON.parse(sc.decode(msg.data)) as Req) };
} catch (err) {
// The caller is told, rather than left to time out: a handler that threw is a
// different failure from a tool nobody serves, and only one of them is worth retrying.
reply = { error: err instanceof Error ? err.message : String(err) };
// **A refused subscription is said, never fatal** (novox/hq 04-ISSUES/218, as 217 for the
// announcements). The grants are the mesh's word on what this account may answer; a subject
// they leave out — a seat claimed here and held elsewhere — costs that subject, never the
// module's other tools, its handlers and its provisioning. Unhandled, the refusal ended the
// process and a module's runtime crash-looped on 2026-10-04.
try {
for await (const msg of sub) {
let reply: { result?: Res; error?: string; node?: string };
try {
reply = { result: await handler(JSON.parse(sc.decode(msg.data)) as Req) };
} catch (err) {
// The caller is told, rather than left to time out: a handler that threw is a
// different failure from a tool nobody serves, and only one of them is worth retrying.
reply = { error: err instanceof Error ? err.message : String(err) };
}
if (node) reply.node = node;
msg.respond(sc.encode(JSON.stringify(reply)));
}
if (node) reply.node = node;
msg.respond(sc.encode(JSON.stringify(reply)));
} catch (err) {
console.log(`[mesh-tools] the bus refused ${subject}: ${err instanceof Error ? err.message : String(err)}; ` +
"not served here, and the rest serves on");
}
})();
return () => sub.unsubscribe();