Skip to content

fix(meshcore): reduce set_out_path timeout and improve error message#3665

Merged
Yeraze merged 1 commit into
mainfrom
claude/great-dijkstra-4eevj0
Jun 23, 2026
Merged

fix(meshcore): reduce set_out_path timeout and improve error message#3665
Yeraze merged 1 commit into
mainfrom
claude/great-dijkstra-4eevj0

Conversation

@Yeraze

@Yeraze Yeraze commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Fixes #3664

Summary

When saving a manually-defined forwarding path on a serial-connected MeshCore device (e.g. xiao nrf on serial-bridge), the UI could hang for a long time before showing "Save failed". The old 30-second native-command timeout was too long, and the 409 error body was misleading.

Root cause: set_out_path makes two serial round-trips (getContacts() to look up the contact object, then setContactPath() to write the new path). On a slow or unresponsive device/serial-bridge the first operation never returns, keeping the serial port busy. A second save attempt then queued behind the lingering first operation, stacking up two 30-second hangs.

Changes

  • meshcoreManager.ts: Pass an explicit 12 s timeout to sendBridgeCommand('set_out_path', …) instead of relying on the 30 s default. Append a connection-hint to the WARN log when the failure is a timeout.
  • meshcoreRoutes.ts: Replace the misleading 409 error body ("contact may be unknown, source disconnected, or not a Companion device") with an actionable message ("device did not respond in time — verify the device is connected and try again").

Test plan

  • All existing out-path route tests still pass (npx vitest run src/server/routes/meshcoreRoutes.test.ts — 156 tests green)
  • On a responsive device, Save Path completes normally (well under 12 s)
  • On an unresponsive device, "Save failed" appears within ~12 s instead of ~30 s+
  • Server WARN log for a timeout now includes "check serial/TCP connection to the device"

🤖 Generated with Claude Code

https://claude.ai/code/session_01GAhBrRAohyXfN1M7bMHRoy


Generated by Claude Code

…3664)

When a serial-connected device (e.g. xiao nrf on serial-bridge) fails to
acknowledge the CMD_ADD_UPDATE_CONTACT command, the old 30 s default left
the "Define forwarding path" UI stuck in a saving state for far too long.

- Set an explicit 12 s native-command timeout for set_out_path, which is
  generous for a responsive device while failing fast for an unresponsive one
- Append a hint to the server WARN log when the failure is a timeout so
  operators can distinguish connection issues from other failures
- Replace the misleading 409 error body ("contact may be unknown …") with
  an actionable message: "device did not respond in time, verify connection"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GAhBrRAohyXfN1M7bMHRoy
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

Claude finished @Yeraze's task —— View job


PR Review

  • Read changed files
  • Analyze code quality and best practices
  • Check for potential bugs or issues
  • Review test coverage

This is a small, focused fix that addresses a real UX pain point. The change is well-scoped and the code quality is solid. A few observations:

meshcoreManager.ts — Timeout reduction

The 12 s timeout is reasonable for the described two-round-trip scenario (getContacts() + setContactPath()). The comment at src/server/meshcoreManager.ts:2297–2298 explains the reasoning clearly.

Minor observation: The timeout detection uses a substring check (response.error?.includes('timeout')). This works fine for now, but it couples the hint to whatever error string meshcore.js happens to produce on timeout. If that upstream error message ever changes (e.g., capitalisation or phrasing), the hint silently disappears without any test failure. A more robust approach would be a typed error code or a dedicated isTimeout flag on BridgeResponse — but that would be a larger refactor and is out of scope for this fix.

Consistency note: The shareContact path at meshcoreRoutes.ts:713 already distinguishes timeouts from other failures and returns 504 instead of 409, with a regex test (/did not respond|timeout/i). The set_out_path path still returns 409 on timeout. It may be worth aligning these so timeouts consistently yield 504 (Gateway Timeout), but again that's a broader cleanup rather than a blocker for this fix.

meshcoreRoutes.ts — Error message

The new message ("Set out_path failed — the device did not respond in time. Verify the device is connected and try again.") at line 673 is an improvement over the old generic message.

Observation: The old error message distinguished "contact may be unknown" from "source disconnected" — these were useful hints for cases where the command failed for a reason other than a timeout. With this change, any non-success from setContactOutPath now returns the timeout-specific message, even if the failure was actually because the device was not connected at all or the contact was missing. This is a minor accuracy regression for the non-timeout failure modes. Given the simplified boolean return from setContactOutPath, there isn't currently a way to differentiate these at the route layer without a more substantial refactor — just worth noting.

Test coverage

The existing test at meshcoreRoutes.test.ts:1672 covers the 409 path for setContactOutPath returning false, but doesn't assert the error message body. Adding a check like expect(response.body.error).toMatch(/did not respond in time/) would ensure the improved message is tested and doesn't silently regress. Not a blocking issue given it's a display string, but a simple addition.


Summary: The fix is correct and well-targeted. The 12 s timeout is sensible, the log hint is helpful for operators, and the new error message is more actionable for users. The observations above are all minor polish items and none are blockers for merging.

public_key: publicKey,
out_path: outPathBytes,
});
}, 12000);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

named const ?

@Yeraze Yeraze merged commit bacb929 into main Jun 23, 2026
21 checks passed
@Yeraze Yeraze deleted the claude/great-dijkstra-4eevj0 branch June 23, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Meshcore: Hang after save in "Define forwarding path"

3 participants