fix(sdk): abort fromDevice pipe on MeshClient.disconnect#1312
Conversation
pipeTo(decodePacket) was started without an AbortSignal, so disconnect closed toDevice/transport while the inbound pipe kept the readable locked. That left serial/BLE ports busy and caused "port is already open" on reconnect. Abort the fromDevice pipe and await settlement before transport.disconnect(). Carried as a pnpm patch in Colorado-Mesh/mesh-client against @meshtastic/core.
|
@rinchen is attempting to deploy a commit to the Meshtastic Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesDevice decoding lifecycle
Estimated code review effort: 2 (Simple) | ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/sdk/src/core/client/MeshClient.ts (1)
151-152: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLog unexpected errors from the decoding pipe.
Silently swallowing all errors prevents unhandled promise rejections for expected
AbortErrors, but it also hides underlying transport or stream errors that might occur during normal operation.Consider logging non-abort errors to aid in debugging:
♻️ Proposed refactor
- // Swallow abort/cancel rejection so an unhandled rejection does not surface. - void this._fromDevicePipe.catch(() => {}); + // Swallow abort/cancel rejection so an unhandled rejection does not surface. + void this._fromDevicePipe.catch((err) => { + if (err instanceof Error && err.name !== "AbortError") { + this.log.error(Emitter[Emitter.ConnectionStatus], "Device decoding pipe failed", err); + } + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/sdk/src/core/client/MeshClient.ts` around lines 151 - 152, Update the _fromDevicePipe rejection handler in MeshClient to ignore only expected abort/cancel errors and log all other decoding, transport, or stream errors. Preserve the existing prevention of unhandled rejections while ensuring unexpected errors include their details in the client’s established logging mechanism.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/sdk/src/core/client/MeshClient.ts`:
- Around line 358-366: Update disconnect() so this._fromDeviceAc.abort() and
awaiting this._fromDevicePipe occur before awaiting
this.transport.toDevice.close(). Wrap the writable close in a try/catch to
tolerate expected physically disconnected transport errors, then ensure
this.transport.disconnect() still executes so teardown completes.
---
Nitpick comments:
In `@packages/sdk/src/core/client/MeshClient.ts`:
- Around line 151-152: Update the _fromDevicePipe rejection handler in
MeshClient to ignore only expected abort/cancel errors and log all other
decoding, transport, or stream errors. Preserve the existing prevention of
unhandled rejections while ensuring unexpected errors include their details in
the client’s established logging mechanism.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2e04c58c-3393-44ce-b84e-291d961c6e48
📒 Files selected for processing (1)
packages/sdk/src/core/client/MeshClient.ts
Review feedback: toDevice.close() can reject on a physically disconnected transport, which previously skipped the abort and left the pipe locked. Abort first, tolerate writable close errors, and log non-abort decoding pipe failures instead of swallowing everything.
DOMException abort rejections are not instanceof Error in all runtimes, so check err?.name directly and stringify non-Error reasons. Include the caught error detail when toDevice.close() fails during disconnect.
…down (#693) * chore: track upstream patch PRs and harden Meshtastic disconnect teardown - Add patches/README.md with upstream PR links (or intentionally-local rationale) for every pnpm.patchedDependencies overlay. - Record ratspeak/rsReticulum#11 and ratspeak/rsLXMF#4 in the Ratspeak overlay README and update.sh RATSPEAK_PATCH_ENTRIES so pnpm run update can warn on merge. - Align @jsr/meshtastic__core patch with meshtastic/web#1312 review feedback: abort the fromDevice pipe before awaiting toDevice.close, tolerate writable close errors on abrupt disconnect, and log non-AbortError decoding pipe failures. * fix: address CodeRabbit review on Meshtastic disconnect patch - Drop the instanceof Error guard in the inbound pipe catch so DOMException abort/stream rejections are classified by name, and stringify non-Error reasons for the log. - Include the caught error detail in the toDevice.close() debug log. - Document why disconnect yields three microtask ticks before releasing the transport.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary
transport.fromDevice.pipeTo(decodePacket(this))with anAbortControllersignal.disconnect(), abort the inbound pipe and await settlement beforetransport.disconnect().Context
Colorado-Mesh/mesh-client carries an equivalent fix as a pnpm patch against
@jsr/meshtastic__core@2.6.6(MeshDevice). The SDK has since moved toMeshClientin this monorepo, but the unabortedpipeTopattern remains.packages/transport-web-serialalready creates a per-instancetoDeviceStreamand aborts cleanly; this PR alignsMeshClientinbound teardown with that pattern.Test plan
Summary by CodeRabbit