fix(miner): fail closed when a chat-action handler throws#7049
Conversation
dispatchChatAction wrapped its paramsValidator call in a try/catch
("fail closed") but left the next line, await registered.handler(request),
unguarded -- a throwing handler became an unhandled rejection instead of
the module's typed { ok, status } contract every other failure path
returns.
Wrap the handler call in try/catch, returning
{ ok: false, status: "handler_error", action } on throw. The distinct
handler_error status lets a caller tell an execution failure from a
validation failure; the thrown value is not surfaced (it may carry
external detail), matching the sibling fail-closed paths in sentry.js
and pretooluse-hook.js.
Closes JSONbored#6989
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7049 +/- ##
==========================================
+ Coverage 93.74% 95.98% +2.23%
==========================================
Files 692 609 -83
Lines 68706 48137 -20569
Branches 18760 15132 -3628
==========================================
- Hits 64409 46202 -18207
+ Misses 3302 1118 -2184
+ Partials 995 817 -178
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-17 19:57:17 UTC
Review summary Nits — 2 non-blocking
Flagged checks (non-blocking)
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
What
dispatchChatAction(packages/loopover-miner/lib/chat-action-dispatch.js) wraps itsparamsValidatorcall in a try/catch — explicitly "fail closed" — but the next line,await registered.handler(request), was unguarded. A handler that throws (e.g. a network error from a governor action) would surface as an unhandled rejection instead of the module's own typed{ ok, status }contract that every other failure path returns.This is latent today (the dashboard-chat REST endpoint that invokes it is still an open epic, #6839), but wiring it live would turn any handler throw into an unhandled rejection.
How
Wrap
registered.handler(request)in try/catch, returning{ ok: false, status: "handler_error", action }on throw. The distinct"handler_error"status (vs"invalid_params") lets a caller tell an execution failure apart from a validation failure.The thrown value is deliberately not echoed back in the result. A handler wraps arbitrary action work (e.g. a network call), so its error could carry external detail — the sibling fail-closed paths named in the issue (
sentry.js,pretooluse-hook.js) likewise swallow rather than surface the thrown value. Fail-closed with a typed status, no raw error string.Validation
Tests added to the existing
test/unit/miner-chat-action-dispatch.test.ts: a handler throwing anErrorand a handler throwing a non-Errorboth fail closed with the same{ ok: false, status: "handler_error", action }shape. Confirmed both fail against the unfixed code (unhandled rejection) and pass with the fix; 100% statement and branch coverage on the file.Closes #6989