-
Notifications
You must be signed in to change notification settings - Fork 968
fix(host-service): unstrand tunnel reconnect; wire relay Sentry #4537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -302,7 +302,14 @@ export class TunnelClient { | |||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private cleanupChannels(): void { | ||||||||||||||||||||||||||||||||||||||||
| for (const channel of this.localChannels.values()) { | ||||||||||||||||||||||||||||||||||||||||
| channel.ws.close(1001, "Tunnel disconnected"); | ||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||
| channel.ws.close(1000, "Tunnel disconnected"); | ||||||||||||||||||||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||||||||||||||||||||
| console.warn( | ||||||||||||||||||||||||||||||||||||||||
| "[host-service:tunnel] error closing local channel ws", | ||||||||||||||||||||||||||||||||||||||||
| err, | ||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| this.localChannels.clear(); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
303
to
315
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: packages/host-service/src/tunnel/tunnel-client.ts
Line: 303-310
Comment:
The empty `catch {}` silently discards any error that isn't the now-fixed 1001 code issue. Since the primary fix is the `1000` code change, the try/catch is purely defensive, but a silent swallow means future `ws.close()` problems on cleanup will be invisible in logs.
```suggestion
private cleanupChannels(): void {
for (const channel of this.localChannels.values()) {
try {
channel.ws.close(1000, "Tunnel disconnected");
} catch (err) {
console.warn("[host-service:tunnel] error closing local channel ws", err);
}
}
this.localChannels.clear();
}
```
How can I resolve this? If you propose a fix, please make it concise.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch — applied in 9827893. With |
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onUncaughtExceptionIntegrationandonUnhandledRejectionIntegrationare auto-enabled by default in@sentry/node. Passing them in theintegrations: [...]array form adds a second copy on top of the defaults rather than replacing them. The default copy hasexitEvenIfOtherHandlersAreRegistered: true, so it will still callprocess.exit()unconditionally — directly defeating the intent of this PR. Every uncaught exception will also be captured twice by Sentry (once by each instance). Use the function form to filter out the defaults first, then supply the customised replacements.Prompt To Fix With AI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified against
@sentry/core@10.46.0source (integration.js:filterDuplicates+getIntegrationsToSetup): the array form does dedupe byname, and a user instance replaces a default of the same name (defaults are taggedisDefaultInstance = true; the merge rule "never want a default instance to overwrite an existing user instance" runs in our favor since user integrations come after defaults in the merged array).Also verified
@sentry/node-core@9.47.1onUncaughtExceptionIntegrationsource: its built-in default forexitEvenIfOtherHandlersAreRegisteredisfalse, nottrue. So even the default wouldn't unconditionally exit.So the array form is fine here — single instance with our config, no exit unless no other handlers are attached.
You did sniff out a real adjacent issue though: Sentry's integration unconditionally calls
captureExceptionitself, and ourprocess.on('uncaughtException'|'unhandledRejection')handlers were also callingcaptureSentryException— double captures. Fixed in 9827893 by slimming the handlers to just log (they still need to exist so Sentry's "other handlers attached" check stays true, keeping the process alive).